获取管道命令的退出代码工作正常。
echo "ABC" | false | true
echo ${PIPESTATUS[0]} ${PIPESTATUS[1]} ${PIPESTATUS[2]}
#Output is 0 1 0
Run Code Online (Sandbox Code Playgroud)
但是当我将输出分配给一个变量时,无法获得退出代码。
TEST=$(echo "ABC" | false | true)
echo ${PIPESTATUS[0]} ${PIPESTATUS[1]} ${PIPESTATUS[2]}
#Output is 0
Run Code Online (Sandbox Code Playgroud)
如何获取管道进程的退出代码?
Bash 命令替换发生在子 shell 中,因此这些值存在但仅在该子 shell 内。您将看到作业中${PIPESTATUS[0]}的 反映(如果您以 结束替换,则会出现这种情况)。$?1| false
我已经更改了您的示例以实际包含一些输出。这也适用于原始代码。
\n\n# without command substitution\necho "ABC" | false | echo "DEF"\necho "${PIPESTATUS[*]}"\n\necho "---"\n\n# within command substitution\nTEST="$( echo "ABC" | false | echo "DEF"; printf :%s "${PIPESTATUS[*]}" )"\ndeclare -a PIPESTATUS2=( ${TEST##*:} ) # make array w/ content after final colon\nif [[ -n "${TEST%:*}" ]]; then # if there was original output\n TEST="${TEST%:*}" # remove trailing results from $TEST\n TEST="${TEST%$\'\\n\'}" # remove trailing \\n like plain $(\xe2\x80\xa6)\nelse\n TEST="" # no original output -> empty string\nfi\n\necho "$TEST"\necho "${PIPESTATUS2[*]}"\nRun Code Online (Sandbox Code Playgroud)\n\n输出:
\n\nDEF\n141 1 0\n---\nDEF\n141 1 0\nRun Code Online (Sandbox Code Playgroud)\n\n退出代码 141false来自提前终止管道 ( SIGPIPE )的事实。
这基本上只是使用冒号作为分隔符将子 shell 的$PIPESTATUS数组附加到存储的值(任何非数字都可以;我选择了一个不需要转义的值),然后将其从响应中取出,用$PIPESTATUS2这些值填充数组。删除最后的换行符是另一种攻击。我们可以使用它作为分隔符,但是如果原始输出没有被换行符终止,那么这就会中断。
TEST=$( echo "ABC" | false | true; exit ${PIPESTATUS[0]} )\necho $? # 141 from `echo "ABC"\nRun Code Online (Sandbox Code Playgroud)\n\n更复杂的 POSIX 兼容解决方案(当您可以使用一些黑魔法时就不需要了):在著名的Csh 编程认为有害的$PIPESTATUS\xc2\xa71d 中搜索“考虑管道”,然后将其适应您的情况符合 POSIX 的需求。如果您是那种需要避免 bash 和真实语言的程序员,那么这将是不平凡的,但非常有教育意义。
| 归档时间: |
|
| 查看次数: |
1509 次 |
| 最近记录: |