Let's say I do this in a unix shell
$ some-script.sh | grep mytext
$ echo $?
this will give me the exit code of grep
but how can I get the exit code of some-script.sh
EDIT
Assume that the pipe operation is immutable. ie, I can not break it apart and run the two commands seperately
There are multiple solutions, it depends on what you want to do exactly.
The easiest and understandable way would be to send the output to a file, then grep for it after saving the exit code:
tmpfile=$(mktemp)
./some-script.sh > $tmpfile
retval=$?
grep mytext $tmpfile
rm tmpfile
A trick from the comp.unix.shell FAQ (#13) explains how using the pipeline in the Bourne shell should help accomplish what you want:
You need to use a trick to pass the exit codes to the main
shell. You can do it using a pipe(2). Instead of running
"cmd1", you run "cmd1; echo $?" and make sure $? makes it way
to the shell.
exec 3>&1
eval `
# now, inside the `...`, fd4 goes to the pipe
# whose other end is read and passed to eval;
# fd1 is the normal standard output preserved
# the line before with exec 3>&1
exec 4>&1 >&3 3>&-
{
cmd1 4>&-; echo "ec1=$?;" >&4
} | {
cmd2 4>&-; echo "ec2=$?;" >&4
} | cmd3
echo "ec3=$?;" >&4
If you're using bash:
PIPESTATUS
An array variable (see Arrays) containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command).
There is a utility named mispipe
which is part of the moreutils package.
It does exactly that: mispipe some-script.sh 'grep mytext'
First approach, temporarly save exit status in some file. This cause you must create subshell using braces:
(your_script.sh.pl.others; echo $? >/tmp/myerr)|\ #subshell with exitcode saving
grep sh #next piped commands
exitcode=$(cat /tmp/myerr) #restore saved exitcode
echo $exitcode #and print them
another approach presented by Randy above, simplier code implementation:
some-script.sh | grep mytext
echo ${PIPESTATUS[0]} #print exitcode for first commands. tables are indexted from 0
its all. both works under bash (i know, bashizm). good luck :)
both approaches does not save temporarly pipe to physical file, only exit code.