7

假设我在 unix shell 中执行此操作

$ some-script.sh | grep mytext

$ echo $?

这会给我退出代码grep

但我怎样才能得到退出代码some-script.sh

编辑

假设管道操作是不可变的。即,我无法将其拆分并分别运行这两个命令

4

5 回答 5

5

有多种解决方案,这取决于你想要做什么。

最简单易懂的方法是将输出发送到文件,然后在保存退出代码后对其进行 grep:

tmpfile=$(mktemp)
./some-script.sh > $tmpfile
retval=$?
grep mytext $tmpfile
rm tmpfile
于 2010-05-17T18:29:37.297 回答
4

comp.unix.shell FAQ (#13)中的一个技巧解释了如何在 Bourne shell 中使用管道来帮助完成你想要的:

   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
于 2011-01-25T06:04:56.730 回答
2

如果您使用的是 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). 
于 2010-05-17T18:32:38.527 回答
2

有一个名为的实用程序mispipe,它是moreutils包的一部分。

它正是这样做的:mispipe some-script.sh 'grep mytext'

于 2012-11-11T12:37:56.447 回答
0

第一种方法,将退出状态暂时保存在某个文件中。这导致您必须使用大括号创建子shell:

(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

上面 Randy 提出的另一种方法,更简单的代码实现:

some-script.sh | grep mytext
echo ${PIPESTATUS[0]} #print exitcode for first commands. tables are indexted from 0

它的全部。两者都在 bash 下工作(我知道,bashizm)。祝你好运:) 两种方法都不会将临时管道保存到物理文件,只会退出代码。

于 2013-08-23T07:23:05.090 回答