问题
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
回答1:
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
回答2:
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
回答3:
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).
回答4:
There is a utility named mispipe
which is part of the moreutils package.
It does exactly that: mispipe some-script.sh 'grep mytext'
回答5:
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.
来源:https://stackoverflow.com/questions/2851622/unix-shell-getting-exit-code-with-piped-child