Hi Alan,
The < and > operators are not parameters to the 'tr' program.  Instead, 
they're special characters interpreted by the shell (in this case, 
QShell).  They're used to tell the shell that standard input should be 
read from one file (test.txt), and standard output should be written to 
another file (test2.txt).
These are services provided by the shell... so you can't use them 
directly from spawn().  Spawn() just runs a program, it doesn't have 
shell capabilities.
Typically the reason you use spawn() instead of simply calling the 
STRQSH CL command is because it lets you map descriptors from one job to 
another.  so you can map the descriptor for stdin and stdout, thus 
letting you send/receive data directly to your program from the API. 
Thus, your descriptor mapping in effect provides the same capabilities 
that the > and < operators do in the shell.
I hope that made sense, because I'm really struggling with how to 
explain this without teaching you Unix from the ground up!!
Anyway, it's possible to run an actual shell from spawn(), and if you do 
that, you can get the shell's capabilities.  So the following code would 
be more or less equivalent to STRQSH:
parm(1) = '/usr/bin/qsh' + x'00';
parm(2) = '-c' + x'00';
parm(3) = 'tr ''|'' ''\n'' < /home/alanc/test.txt' +
          ' > /home/alanc/test2.txt' + x'00';
Alternately, if you don't need the shell's capabilities, you can do 
something like this:
infile = open('/path/to': O_RDONLY+O_TEXTDATA);
outfile = open('/path/to': O_WRONLY+O_CREAT:M_RDWR);
now call the spawn() API.  Map the descriptor number in "infile" to 
descriptor 0 in the spawned job.  Map the descriptor number in "outfile" 
to descriptor 1 in the spawned job.  This effectively tells the spawn to 
read from infile, and write to outfile.
When you make the parameter list, you'd make something like this:
parm(1) = '/usr/bin/tr' + x'00';
parm(2) = '|' + x'00';
parm(3) = x'2500';
Basically you tell spawn() to run the tr program, pass a pipe in the 
first parameter, and x'25' (EBCDIC code for LF) in the second parameter.
Since you're not going through the shell, you can't use \n... at least, 
I don't think you can?  Depends on how 'tr' was written.
After the spawn() call, close the infile and outfile.  Use waitpid() to 
wait for the spawned job to complete.
That would be more efficient than running the shell because fewer jobs 
would have to be submitted, but it's obviously a bit more work, and 
requires more knowledge on your part.
Hope this makes sense... I'm short on time, so this is just off the top 
of my head, I didn't write a program to test it.
Alan Campin wrote:
This may be a question that only Scott can answer. 
Given the following string
/bin/tr '|' \n < /home/alanc/test.txt > /home/alanc/test2.txt
which works from the command line in qsh I want to call the spawn api in
an RPG/ILE program.
The spawn API expects that the 5th parameters be an array of null
terminated strings with the parameters.
My question is given the above string, how many null terminated strings
would I send? 
Three?
'''|'' \n'
'< /home/alanc/test.txt'
'> /home/alanc/test2.txt'
Four?
'''|'''
'\n'
'< /home/alanc/test.txt'
'> /home/alanc/test2.txt'
Six?
'''|'''
'\n'
'<'
'/home/alanc/test.txt'
'>'
'/home/alanc/test2.txt'
I keep getting the following errors:
                QP2SHELL Error Log 
                                      
  Run Date:  5/08/07  Time: 19:59:57  User:
tr: 0653-712 The combination of options and String parameters is not
legal.  
Usage: tr [ -c | -cds | -cs | -ds | -s ] [-A] String1 String2
       tr { -cd | -cs | -d | -s } [-A] String1 
I know there is trick. I just cannot figure out what it is. 
The code can execute other commands without a problem but it just
doesn't like this one. 
Thanks for the help.
                              
As an Amazon Associate we earn from qualifying purchases.