unix shell, getting exit code with piped child

六月ゝ 毕业季﹏ 提交于 2019-12-01 17:00:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!