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.