https://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another
BASH SHELL中,通常使用 $?
來獲取上一條命令的返回碼。
對於管道中的命令,使用$?
只能獲取管道中最后一條命令的返回碼,例如
下面的例子中/not/a/valid/filename
是一個不存在的文件
cat /not/a/valid/filename | cat
第一個cat失敗,第二個cat成功,所以$?的值為0
這種情況下,可以使用 $PIPESTATUS
來獲取管道中每個命令的返回碼。
注意:
-
1、PIPESTATUS 是一個數組,第一條命令的返回碼存儲在
${PIPESTATUS[0]}
,以此類推,上例中執行完管道中所有的命令后,PIPESTATUS
數組第一個元素值為1,第二個元素值為0 -
2、如果前一條命令不是一個管道,而是一個單獨的命令,命令的返回碼存儲為
${PIPESTATUS[0]}
,此時${PIPESTATUS[0]}
同$?值相同(事實上,PIPESTATUS最后一個元素的值總是與$?的值相同) -
3、每執行一條命令,切記PIPESTATUS都會更新其值為上一條命令的返回碼,
cat /not/a/valid/filename|cat
if [ ${PIPESTATUS[0]} -ne 0 ]; then echo ${PIPESTATUS[@]}; fi
上例中執行完管道后,`${PIPESTATUS[0]}`值為1,`${PIPESTATUS[1]}`值為0
但是上面的腳本執行完成后,輸出為0,這是因為if 分支的測試命令
[root@test output]# cat a.sh
#!/bin/sh
a=3
if [ $a -gt 4 ]
then
echo "1111111"
exit 1
fi
echo "222222"
exit 0
[root@test output]# cat b.sh
#!/bin/sh
sh a.sh | tee >>a.log
aa=${PIPESTATUS[0]}
if [ $aa -ne 0 ]
then
echo "aaaaaaaaaaaaaaaa"
fi