Sharon,

reading the ParseCommandParms() method, I found a detail that in my opinion
should be modified. When calling a executable from shell, one can give an
empty string (length = 0) as a parameter using two consecutive quotes between
two spaces. Such a pair of qoutes is ignored by ParseCommandParms(). That is,
there is no way to give an empty string as a param.

The following small patch would fix this, I guess (have not tested):

--- STAFProcess.cpp.orig        2009-07-14 16:28:41.000000000 +0200
+++ STAFProcess.cpp     2009-07-14 16:31:00.000000000 +0200
@@ -1352,6 +1352,7 @@ int ParseCommandParms(STAFString &comman
         else if ((currChar == dquote) && !inEscape)
         {
             inQuotes = !inQuotes;
+            argReady = 1
             continue;
         }
         else if ((currChar == bslash) && !inEscape)

HTH
Bodo


________________________________
From: Sharon Lucas [mailto:luc...@us.ibm.com]
Sent: Monday, July 13, 2009 11:33 PM
To: Strösser, Bodo
Cc: 'staf-users@lists.sourceforge.net'
Subject: Fw: [staf-users] STAX: How to format <parms> element content


Bodo,

Here's how you can run this program with arguments containing double quotes and 
single quotes in the default mode (instead of SHELL mode):

# STAF local PROCESS START COMMAND "testquotes" PARMS "1 \"\\\"2 3\\\"\" \"'4 
5'\"" RETURNSTDOUT STDERRTOSTDOUT RETURNFILE /tmp/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'#

    }
  ]
}

Here's how you run this same command via a <process> element in a STAX job:

  <process name="'TestProc'">
    <location>machine</location>
    <command>'testquotes'</command>
    <parms>"1 \"\\\"2 3\\\"\" \"'4 5'\""</parms>
    <stderr mode="'stdout'"/>
    <returnstdout/>
  </process>

# cat /myhome/testcmd.out
Parameter 1: #1#
Parameter 2: #"2 3"#
Parameter 3: #'4 5'#

--------------------------------------------------------------
Sharon Lucas
IBM Austin,   luc...@us.ibm.com
(512) 286-7313 or Tieline 363-7313

----- Forwarded by Sharon Lucas/Austin/IBM on 07/13/2009 04:19 PM -----
Sharon Lucas/Austin/IBM

07/13/2009 12:19 PM

To
"Strösser, Bodo" <bodo.stroes...@ts.fujitsu.com>
cc
"'staf-users@lists.sourceforge.net'" <staf-users@lists.sourceforge.net>
Subject
Re: [staf-users] STAX: How to format <parms> element 
contentLink<Notes://d27mc602/86255F010062DDC4/32547D7F59F9E7E38525613200556E77/E8D415E0BACFD4C5862575F2003D6C11>




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

------------------------------------------------------------------------------
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

Reply via email to