perl -e 'system ("crontab1 -l");print $?'
returns -1 as expected (program crontab1 doesn't exist)
perl -e 'system ("crontab1 -l|grep blah");print $?'
returns 256.
What is the way to check the status of the first (or both) programs?
perl -e 'system ("crontab1 -l");print $?'
returns -1 as expected (program crontab1 doesn't exist)
perl -e 'system ("crontab1 -l|grep blah");print $?'
returns 256.
What is the way to check the status of the first (or both) programs?
You are getting the exit status of the entire command, just as you should. If you want the exit status separately, you're going to have to run the commands separately.
#!/usr/bin/perl -e
system("crontab1 -l > /tmp/junk.txt"); print $?;
system("grep blah /tmp/junk.txt"); print $?;
as an example.
If you want to check the status, don't put them all in the same system. Open a reading pipe to the first program to get its output then open another pipe to the other program.
The operating system returns an exit status only for the last program executed and if the OS doesn't return it, perl can't report it.
I don't know of any way to get at the exit code returned by earlier programs in a pipeline other than by running each individually and using temporary files instead of pipes.
Remember, you're supposed to use $?>>8 to get the exit code, not $?
perl -e 'system("set -o pipefail;false | true");print $?>>8,"\n"'
1
This ("pipefail") only works if your shell is bash 3. Cygwin and linux ship with it; not sure about mac.
You should be aware that 256 is an error return. 0 is what you'd get on success:
perl -e 'system("true");print $?>>8,"\n"'
0
I didn't know system returned -1 for a single command that isn't found, but $?>>8 should still be non-zero in that case.
If you tolerate using something other than system
, there are easier solutions. For example, the results
method in IPC::Run returns all exit codes of the chain.
What is the way to check the status of the first (or both) programs?
There is no such way, at least, not as you have constructed things. You may have to manage sub-processes yourself via fork(), exec() and waitpid() if you must know these things.
Here is roughly what is happening in your code fragment.
perl
's system() spawns a shell, and perl
wait()s for that subprocess to terminate.
The shell sets up a pipeline:
grep
on the read-end of the pipecrontab1
anywhere in $PATH
, and exit()s 127 (on my system, that is, where 127 is the shell indicating failure to find a program to run).grep
detects end-of-file on its input and, having matched nothing, exit()s 1.
The shell exit()s with the exit code of the last process in the pipeline, which, again, is 1.
perl
detects the shell's exit code of 1, which is encoded in $?
as 256.
(256 >> 8 == 1)