假设我有一个名为Foo.c
的C程序,它打印一些东西并返回一个名为rc
的值,我在shell程序中执行如下:
foobar=$(Foo | tail -1)
现在,变量foobar具有程序Foo
的最后打印值。但是在不打扰这个的情况下,我希望在我的shell程序中获得程序的返回码rc
。
答案 0 :(得分:13)
如果您使用的是bash
shell,则可以使用PIPESTATUS
数组变量来获取pipe
进程的状态。
$ tail sat | wc -l
tail: cannot open ‘sat’ for reading: No such file or directory
0
$ echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}"
1 0
$
来自man bash
:
<强> PIPESTATUS 强>
一个数组变量,包含最近执行的前台管道中的进程的退出状态值列表(可能只包含一个命令)。
答案 1 :(得分:13)
您可以使用&#34;设置-o pipefail&#34;选项。
[root@myserver Test]# set -o pipefail
[root@myserver Test]# ./a.out | tail -l
[root@myserver Test]# echo $?
100
这里我的程序a.out返回100.
或者另一种选择是使用pipestatus环境变量。你可以在这里读到它。 http://www.linuxnix.com/2011/03/pipestatus-internal-variable.html
答案 2 :(得分:6)
这会将Foo
的输出的最后一行指定为foobar
,并将Foo的退出代码指定给code
:
{ read -r foobar; read code; } < <( (Foo; echo $? ) | tail -2)
<(...)
构造称为流程替换。在上面的代码中,read
命令从进程替换中接收stdin。由于tail -2
,进程替换总共产生两行。第一行是Foo
生成的最后一行,它被分配给foobar
。第二个分配给code
。
第一个和第二个<
之间的空格是必不可少的。
创建函数Foo后,可以测试以上内容:
$ Foo() { echo "Testing"; false; }
$ { read -r foobar; read code; } < <( (echo "Testing"; false; echo $? ) | tail -2)
$ echo "foobar=$foobar code=$code"
foobar=Testing code=1
和
$ Foo() { echo "2nd Test"; true; }
$ { read -r foobar; read code; } < <( (Foo; echo $? ) | tail -2)
$ echo "foobar=$foobar code=$code"
foobar=2nd Test code=0
答案 3 :(得分:2)
我担心您必须使用临时文件来存储Foo程序的输出,获取返回码然后执行tail -1。如下所示:
Foo > /tmp/temp_file
ret=$?
foobar=$(tail -1 /tmp/temp_file)
答案 4 :(得分:0)
$?
给出上次执行的命令的返回值。