2010-05-17 45 views
7

比方说,我这样做是在Unix shellUNIX外壳,让退出代码与管道孩子

$ some-script.sh | grep mytext 

$ echo $? 

这会给我的grep

退出代码,但我怎么能得到的退出代码some-script.sh

EDIT

假定管操作是不可变的。也就是说,我不能将它分开,并单独运行这两个命令。

回答

5

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

最简单易懂的方法是将输出发送到文件,然后保存退出代码之后用grep吧:

tmpfile=$(mktemp) 
./some-script.sh > $tmpfile 
retval=$? 
grep mytext $tmpfile 
rm tmpfile 
+0

感谢您的回复,请参阅我的编辑 – Mike 2010-05-17 18:31:26

+3

我明白了。也许这是一个解决方案:'tmpfile = $(mktemp); (./some-script.sh; echo $?> $ tmpfile)| grep mytext; retval = $(cat $ tmpfile)'。这很肮脏,但也许有帮助。 – watain 2010-05-17 18:35:12

+0

然后grep得到'echo $的输出? > tmpfile' – Mike 2010-05-17 18:43:59

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). 
+0

我正在使用sh。我的客户不喜欢bash – Mike 2010-05-17 18:34:04

3

来自comp.unix.shell FAQ(#13)的技巧解释了如何在Bourne外壳中使用管道应该有助于实现您想要的功能:

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 
2

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

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

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 

上述兰迪提出的另一种方法,simplier代码实现:

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

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