命令替换后的管道状态

时间:2010-12-10 15:10:03

标签: bash pipe

我想将一系列命令的结果发送给变量:

variable=$(a | few | commands)

但是,命令替换会重置PIPESTATUS,所以在事后我无法检查它出错的地方。一种解决方案是使用mktemp并暂时将结果放在那里:

variable_file=$(mktemp) || exit 1
a | few | commands > $variable_file
exit_codes="${PIPESTATUS[*]}"
variable=$(<$variable_file)

有更优雅的解决方案吗?

2 个答案:

答案 0 :(得分:7)

有点hacky,但我认为你可以像这样捏造它。

variable=$(a | few | commands; echo ": ${PIPESTATUS[*]}")
PIPESTATUS=(${variable##*: })
variable=${variable%:*}
variable=${variable%$'\n'}

答案 1 :(得分:1)

基于 ephemient's 答案,如果我们需要存储管道命令的输出而不将它们与管道状态代码混合,但我们并不真正关心退出代码本身是什么(只是它们都成功),我们可以这样做:

variable=$(a | few | commands; [[ ${PIPESTATUS[*]} == "0 0 0" ]])

这将检查上述示例中所有管道命令状态的状态,如果其退出代码不是 0,则将 $? 设置为 1 (false)

如果您想使用不同的代码而不是 1 退出,您可以捕获 PIPESTATUS[#] 的内容,例如r_code=${PIPESTATUS[2]},然后使用 (exit ${r_code[2]}) 而不是 false

下面捕获PIPESTATUS的所有代码,确保它们都是0,如果不是,则将退出代码设置为$?的{​​{1}}值:

commands