Bodo,
So, when running your program (I called it testquotes), you have to
specify the arguments as follows when running your test C++ program to get
the arguments parsed as you wanted:
# testquotes 1 "\"2 3\"" "'4 5'"
# cat /myhome/testcmd.out
Parameter 1: #1#
Parameter 2: #"2 3"#
Parameter 3: #'4 5'#
I'll demonstrate first using a STAF PROCESS START request, as whenever a
<process> element is encountered, STAX simply submits a PROCESS START
request under the covers.
If you run this same command with the appropriate escaping via a STAF
PROCESS START request, you get:
# STAF local PROCESS START COMMAND "testquotes" PARMS "1 "\"2 3\"" \"'4
5'\"" RETURNSTDOUT STDERRTOSTDOUT RETURNFILE /myhome/testcmd.out WAIT
Response
--------
{
Return Code: 0
Key : <None>
Files : [
{
Return Code: 0
Data :
}
{
Return Code: 0
Data : Parameter 1: #1#
Parameter 2: #2 3#
Parameter 3: #'4 5'#
}
]
}
And everything is as you expected except that Parameter 2 does not contain
the double quotes as you had wanted. Note that under the covers, STAF
created an argv array as follows, and you can see the argv[2] does not
contain the double quotes as you desired because STAF's
ParseCommandParms() method removes the double quotes:
argv[0]=testquotes
argv[1]=1
argv[2]=2 3
argv[3]='4 5'
However, if you use the SHELL mode and the correct shell quoting for the
"sh" shell , then you can get the results you want. For example, via a
STAF PROCESS START request:
# STAF local PROCESS START SHELL COMMAND "testquotes" PARMS "1 '\"2 3\"'
\"'4 5'\"" RETURNSTDOUT STDERRTOSTDOUT RETURNFILE /myhome/testcmd.out WAIT
Response
--------
{
Return Code: 0
Key : <None>
Files : [
{
Return Code: 0
Data :
}
{
Return Code: 0
Data : Parameter 1: #1#
Parameter 2: #"2 3"#
Parameter 3: #'4 5'#
}
]
}
This works because when using the SHELL mode, STAF is creating the argv
array as follows and relies on the shell to parse the arguments rather
than on STAF's ParseCommandParms() method:
argv[0]=sh
argv[1]=-c
argv[2]=testquotes 1 '"2 3"' "'4 5'"
So, my suggestion is to use the SHELL mode. Here's how you could specify
the PARMS via a <process> element using the shell mode in a STAX job and
have the results you desire:
<process name="'TestProc'">
<location>machine</location>
<command mode="'shell'">'testquotes'</command>
<parms>"1 '\"2 3\"' \"'4 5'\""</parms>
<stderr mode="'stdout'"/>
<returnstdout/>
</process>
Here's the contents of /myhome/testcmd.out after this <process> element
runs (and it contains the output you desired):
# cat /myhome/testcmd.out
Parameter 1: #1#
Parameter 2: #"2 3"#
Parameter 3: #'4 5'#
Now, for more details on what I just discussed.
Note that you can look at the source code for STAF to see you the
parameters are processed on a Unix machine in
src/staf/stafif/unix/STAFProcess.cpp.
a) If you are not using the SHELL mode for the command (like you are
currently doing), then STAF creates the argument array passed to execv (or
execve) as follows:
- A string is created based on the command (possibly with a path added if
one was not provided) + " " + parms. Then STAF's ParseCommandParms()
method in src/staf/stafif/unix/STAFProcess.cpp is called to create a
argument list from this string. See it for specifics of how this argument
list (argv) is created.
- OR-
b) If you use the SHELL mode for the command, then STAF creates the
argument array passed to execv (or execve) as follows:
argv[0] = "sh"
argv[1] = "-c"
argv[2] = command (which is the shell command used with the
command/parms specified with shell substitution performed)
You can google for more information on shell quoting, For example see
"Shell quoting to hide special metacharacters" and "Quoting affects the
number of arguments the shell sees" from
http://teaching.idallen.com/cst8129/05f/notes/week02notes.txt which says:
Shell quoting to hide special metacharacters
- See Notes: quotes.txt - Unix/Linux Shell Command Line Quoting
- a shell interprets many punctuation characters ("metacharacters")
specially
- quotes and backslashes hide special characters from the shell
- quote the shell metacharacters, to stop the shell from helping you
- quotes delimit each argument; they tell the shell where it starts/ends
- quotes are not part of the argument
- two different strengths of quotes
- single quotes are strongest and hide *all* other shell metacharacters
$ echo 'This is a \"nice\" day. I live at $HOME.'
This is a \"nice\" day. I live at $HOME.
- double quotes are weak and hide almost everything,
except they don't hide: \" and $variable expansions, e.g.
$ echo "This is a \"nice\" day. I live at $HOME."
This is a "nice" day. I live at /home/alleni.
- only single quotes stop variable expansion
- both kinds of quotes stop GLOB (wildcard) expansion and blank splitting
- you can also use backslash to hide individual characters from the shell
$ echo It\'s a \* nice day \* today!
It's a * nice day * today!
Quoting affects the number of arguments the shell sees
- See Notes: arguments_and_options.txt
- See Notes: quotes.txt - Unix/Linux Shell Command Line Quoting
- use argv.sh to see how shell creates arguments (can also use ls -d)
(fetch argv.sh.txt from the course Notes area and make it executable)
$ echo " abc "' def ' " ghi " ' jkl '
abc def ghi jkl
$ ./argv.sh " abc "' def ' " ghi " ' jkl '
Argument 0 is [./argv.sh]
Argument 1 is [ abc def ]
Argument 2 is [ ghi ]
Argument 3 is [ jkl ]
--------------------------------------------------------------
Sharon Lucas
IBM Austin, luc...@us.ibm.com
(512) 286-7313 or Tieline 363-7313
Strösser, Bodo <bodo.stroes...@ts.fujitsu.com>
07/13/2009 06:07 AM
To
Sharon Lucas/Austin/i...@ibmus
cc
"'staf-users@lists.sourceforge.net'" <staf-users@lists.sourceforge.net>
Subject
Re: [staf-users] STAX: How to format <parms> element content
Sharon,
thank you again for the hints.
Unfortunately I still don't understand what to do. Especially the process
of breaking the <parms>-string into
single parameters isn't transparent to me.
Let me give an example:
A very simple program is written in C. It just prints its parameters to a
file. Here is the source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int
main(int argc, char **argv)
{
int i;
FILE *fp;
fp = fopen("/myhome/testcmd.out", "w");
if (fp == NULL) {
fprintf(stderr, "Error in fopen(): %s\n",
strerror(errno));
exit(1);
}
for (i = 1; i < argc; i++) {
fprintf(fp, "Parameter %d: #%s#\n", i, argv[i]);
}
exit(0);
}
Before the program is called from STAX via <process>, a Python variable is
set to the contents of the <parms>-string and printed to STAXMon. There
are
three parameters I want to transfer to my program: the first is a single
digit 1
only, the second are the digits 2 and 3 separated by a space and enclosed
by
quotes (which the program should receive, too) and the third parameter are
the
digits 4 and 5 separated by a space and enclosed by single quotes, which
also
are a part of the parameter.
Here is the <script> element:
<script>
testparms = '1 "2 3" \'4 5\''
print "Testparms = #%s#" % testparms
</script>
STAXMon shows:
Testparms = #1 "2 3" '4 5'#
When my program is executed by STAX, it writes to the file testcmd.out:
Parameter 1: #1#
Parameter 2: #2 3#
Parameter 3: #'4#
Parameter 4: #5'#
There are 4 parameters, not 3 and the quotes are not part of the second
parameter. So, I guess, the precise question should be, what are the rules
used in STAF to process the <parms>-string when building the argument
array for the "execv()"?
Or is there a possibility to give a list of strings, one for each
parameter?
Bodo
From: Sharon Lucas [mailto:luc...@us.ibm.com]
Sent: Friday, July 10, 2009 11:45 PM
To: Strösser, Bodo
Cc: 'staf-users@lists.sourceforge.net'
Subject: Re: [staf-users] STAX: How to format <parms> element content
Bodo,
The STAF colon-length-colon format is for an entire option value in a STAF
service request (as talked about in the STAF User's Guide).
You need to understand Python to know what characters in a string like
this need to be replaced. This isn't really a STAF/STAX question, but
more of a Python question on how to construct string literals. Please
read section "Using Python for Expression Evaluation" in the STAX User's
Guide and you can google for more information on Python.
For example, say you wanted to run the following command via a <process>
element in a STAX job:
myCommand -file: "C:\Program Files\myApp" -x: 'Hi'
you could specify:
<parms>"-file: \"C:\\Program Files\\myApp\" -x: 'Hi'"</parms>
or you could specify it as follows:
<parms>'-file: "C:\\Program Files\\myApp" -x: \'Hi\''</parms>
Python documentation provides complete information about how to construct
string literals such as the following information:
"There are several different ways to construct string literals in Python.
String literals can start and end with single quotes or double quotes. In
either case, the other kind of quote can be used safely inside the
literal. Within the quotation marks, special characaters are escaped
using a backslash. The list of escapes is based on C and is slightly
different from Java's escape list. Unlike Java, backslashes followed by
characters not on the following list of escapes are legal in strings, and
are treated merely as normal characters.
Backslash Escape Characters:
Escape character Meaning
---------------- -----------------------------------------
\\ Backslash (\)
\' Single quote (')
\" Double quote (")
\r Carriage return
\t Tab
\uxxxx Unicode 16-bit character value xxxx (hex)
\a Bell (ASCII character number 13)
\b Backspace
\f Formfeed
\n Linefeed or newline
\N{name} Unicode character identified by "name"
\Uxxxxxxxx Unicode 32-bit characer xxxxxxxx (hex)
\v Vertical tab character
\ooo Unicode 8-bit character in octal
\xhh hexadecimal
String literals may also begin and end with either three single or three
double quotes. A triple-quoted string may include newline characters
(which would ordinarily need to be escaped) or individual quotation marks.
"""some
long
string"""
A string literal may also have an r or R before the inital quote, to
indicate a "raw string". Inside a raw string, backslash escape does not
work and backslashes are treated as normal characters. Quotation marks
may be escaped in raw strings, but the backslash stays in the string.
>>> r"c:\program files"
'c:\\program files'
>>> r"\""
'\\"'
Notice that the raw string results in a normal string -- after the string
is created, you can't tell whether itwas created using the raw option. Raw
strings are just a flavor or string literal. They are often used in
regular expressions to keep them from looking even more like random
noise."
So, in the future, you can look at Python documentation to get answers to
questions on Python (instead of posting to the staf-users mailing list).
Note, you also need to be careful when specifying a < or & within a STAX
xml file, or a { in a STAF service request option value that resolves
variables:
- Also, note that XML processors assume that < always starts a tag and
that & always starts an entity reference, so you should avoid using those
characters for anything else. You must use the entity reference <
instead of < and entity reference & instead of & or else you'll get an
XML parsing error.
- Also, note that STAF automatically resolves STAF variables in a PROCESS
START COMMAND and PARMS option, so if you need to specify a {, you need to
escape it with a caret, e.g. ^{
--------------------------------------------------------------
Sharon Lucas
IBM Austin, luc...@us.ibm.com
(512) 286-7313 or Tieline 363-7313
Strösser, Bodo <bodo.stroes...@ts.fujitsu.com>
07/10/2009 03:10 PM
To
"'staf-users@lists.sourceforge.net'" <staf-users@lists.sourceforge.net>
cc
Subject
[staf-users] STAX: How to format <parms> element content
Hi,
when starting a <process> in STAX, parameters for the process must be
specified in the <parms> element.
I need to handle the case of a number of strings containing one parameter
each.
The strings might contain characters like Quotation marks, Single quotes
or
Backslashes. How would I need to prepare the python string for the <parms>
element, so that the parameters are transfered to the process
transparently?
The colon-length-colon method seems not to work here.
Best regards
Bodo
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full
prize
details at:
http://p.sf.net/sfu/Challenge_______________________________________________
staf-users mailing list
staf-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/staf-users
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full
prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
staf-users mailing list
staf-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/staf-users
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
staf-users mailing list
staf-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/staf-users