~~ linux return code with pipeline~~
~~ linux 管道命令中的返回码~~
BASH?SHELL中,通常使用?$??来获取上一条命令的返回码。
Shell Scripting Tutorial - Checking the exit status of ANY command in a pipeline
对于管道中的命令,使用$?只能获取管道中最后一条命令的返回码,例如:
${RUN_COMMAND} 2> "${CUR_DIR}"/weiflow-from-weiclient.log | ${WEIBOX_UTIL_HOME}/rotatelogs.py -n 3 "${CUR_DIR}"/weiflow-from-weiclient.log 500M
使用?$PIPESTATUS来获取管道中每个命令的返回码。
注意:
PIPESTATUS?是一个数组,第一条命令的返回码存储在${PIPESTATUS[0]},以此类推。
如果前一条命令不是一个管道,而是一个单独的命令,命令的返回码存储为${PIPESTATUS[0]},此时${PIPESTATUS[0]}同$?值相同(事实上,PIPESTATUS最后一个元素的值总是与$?的值相同)
每执行一条命令,切记PIPESTATUS都会更新其值为上一条命令的返回码,
??????cat?/not/a/valid/filename|cat
??????if?[?${PIPESTATUS[0]}?-ne?0?];?then?echo?${PIPESTATUS[@]};?fi
??????上例中执行完管道后,${PIPESTATUS[0]}值为1,${PIPESTATUS[1]}值为0
??????但是上面的脚本执行完成后,输出为0,这是因为if?分支的测试命令值为真,然后?PIPESTATUS[0]的值此时被置为0。应当在命令执行完成后立即在同一个测试命令中对所有值进行测试,例如?
??????if?[?${PIPESTATUS[0]}?-eq?1?-a?${PIPESTATUS[1]}?-eq?0?]?;?then?echo?something;?fi
或者先将$PIPESTATUS数组保存下来,以后再处理,例如
??????ret=${PIPESTATUS[@]};
${RUN_COMMAND} 2> "${CUR_DIR}"/weiflow-from-weiclient.log | ${WEIBOX_UTIL_HOME}/rotatelogs.py -n 3 "${CUR_DIR}"/weiflow-from-weiclient.log 500M
exit \${PIPESTATUS[0]}
#!/bin/bash
grep some.machine.example.com /etc/hosts
if [ "$?" -ne "0" ]; then
# The grep command failed to find "some.machine.example.com" in /etc/hosts file
echo "I don't know the IP address of some.machine.example.com"
exit 2
fi
#!/bin/bash
grep some.machine.example.com /etc/hosts 2>&1 | tee /tmp/hosts-results.txt
if [ "$?" -ne "0" ]; then
# Ah - what we get here is the status of the "tee" command,
# not the status of the "grep" command :-(
What you get is the result of the tee command, which writes the results to the display as well as to the /tmp/hosts-results.txt file.
To find out what grep returned, $? is of no use.
Instead, use the ${PIPESTATUS[]} array variable. ${PIPESTATUS[0]} tells us what grep returned, while ${PIPESTATUS[1]} tells us what tee returned.
So, to see what grep found, we can write our script like this:
#!/bin/bash
grep some.machine.example.com /etc/hosts 2>&1 | tee /tmp/hosts-results.txt
if [ "${PIPESTATUS[0]}" -ne "0" ]; then
# The grep command failed to find "some.machine.example.com" in /etc/hosts file
echo "I don't know the IP address of some.machine.example.com"
exit 2
fi
Pipeline (command) | PIPESTATUS shows status of: |
---|---|
grep ... | tee ... |
echo "Grep returned ${PIPESTATUS[0]}" | echo "Grep ... |
echo "Maybe PIPESTATUS isn‘t so useful after all" | echo "Maybe ... |
Because ${PIPESTATUS[]} is a special variable, it changes all the time. However, we can copy this array into another array, which is just a regular array, which will not be changed at all just by running some more commands. Copying an array requires a slightly different syntax to simply copying contents of a variable into another:
#!/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
原文:https://www.cnblogs.com/suanec/p/12405775.html