问题
当我们在linux shell(如bash)中使用管道执行多个命令时,$?
只能获取到最后一条命令的返回码,那么应该怎么获取管道前面的命令的返回码呢,请看下文:
当执行一条管道命令时,linux会使用PIPESTATUS这个数组变量来保存每个管道的返回码。PIPESTATUS[0]
表示管道中第一个命令的返回码,PIPESTATUS[1]
表示第二个命令的返回值,这是一个共享的变量,为避免别的命令改变它的内容,可以将它复制到一个新的数组。
bash
#!/bin/bash
echo "tftf"
true | false | true | false
RC=( "${PIPESTATUS[@]}" )
echo "RC[0] = ${RC[0]}" # true = 0
echo "RC[1] = ${RC[1]}" # false = 1
echo "RC[2] = ${RC[2]}" # true = 0
echo "RC[3] = ${RC[3]}" # false = 1
echo "ftft"
false | true | false | true
RC=( "${PIPESTATUS[@]}" )
echo "RC[0] = ${RC[0]}" # false = 1
echo "RC[1] = ${RC[1]}" # true = 0
echo "RC[2] = ${RC[2]}" # false = 1
echo "RC[3] = ${RC[3]}" # true = 0
echo "fftt"
false | false | true | true
RC=( "${PIPESTATUS[@]}" )
echo "RC[0] = ${RC[0]}" # false = 1
echo "RC[1] = ${RC[1]}" # false = 1
echo "RC[2] = ${RC[2]}" # true = 0
echo "RC[3] = ${RC[3]}" # true = 0
执行上面的bash文件,输出如下所示:
bash
jagitch@jagitch-MS-7B93:~$ source pipeline.sh
tftf
RC[0] = 0
RC[1] = 1
RC[2] = 0
RC[3] = 1
ftft
RC[0] = 1
RC[1] = 0
RC[2] = 1
RC[3] = 0
fftt
RC[0] = 1
RC[1] = 1
RC[2] = 0
RC[3] = 0
一个具体的实例
bash
#!/bin/bash
WEB_SERVER=steve-parker.org
curl -# -f -u ${USERNAME}:${PASSWORD} http://${WEB_SERVER}/ | grep "SomeMessage"
RC=( "${PIPESTATUS[@]}" )
if [ "${RC[0]}" -eq "22" ]; then
# curl returned 22, indicating some error above 400,
# such as: 404 Not Found, 401 Unauthorized, etc.
echo "Invalid credentials"
exit 1
fi
# PIPESTATUS has gone, but we can still inspect RC
if [ "${RC[1]}" -eq "0" ]; then
echo "Grep succeeded"
echo "Web server reported SomeMessage"
else
echo "Web server didn't report SomeMessage"
fi
推荐阅读
1. 使用树梅派搭建Golang、Python、NodeJs的开发服务器