从最后一个管道(stdin)获取退出代码
Posted
技术标签:
【中文标题】从最后一个管道(stdin)获取退出代码【英文标题】:Get exit code from last pipe (stdin) 【发布时间】:2015-08-04 09:42:33 【问题描述】:我希望能够创建一个 bash 函数,该函数可以在管道之前读取命令的退出代码。我不确定是否可以访问它。
echo "1" | grep 2
返回 1 状态码
echo "1" | grep 1
返回 0 状态码
现在我想添加第三个命令来读取状态,用管道:
echo "1" | grep 2 | echo $?
将回显“0”,即使状态码为 1。
我知道我可以使用echo "1" | grep 2 && echo "0" || echo "1"
,但我更喜欢使用管道来编写它。
他们是否仍然这样做(如果它可以在大多数 shell 上工作,例如 bash、sh 和 zsh,那就更好了)
【问题讨论】:
为什么要使用管道?echo "1" | grep 2;echo $?
可以正常工作。
因为我可能还需要来自标准输入的内容。但是,我更喜欢您的解决方案而不是 @mattinbits 的解决方案
听起来像是 XY 问题。为什么需要管道内部的状态?
就像tee
获取标准输入并将其放入文件并将其传递给下一个命令,我希望能够获得状态并将所有内容传递给下一个命令。这样我就可以做echo "1" | debug | long | command | here
,这样我现在就可以调试管道的状态,而不必编写多行(这样可以重复)。这有意义吗?
当我在 bash 中运行一些命令时,我主要使用 debug
函数,所以如果我能在一行中完成,我会更喜欢。
【参考方案1】:
您必须在管道的下一阶段之前获得退出状态。类似的东西
exec 3> debug.txt
echo "1"; echo "$?" >&3; | long | command | here
您不能(轻松)将其封装在一个函数中,因为它需要传递一个正确引用的字符串并通过eval
执行它:
debug ()
eval "$@"
echo $? >&3
# It looks easy in this example, but it won't take long to find
# an example that breaks it.
debug echo 1 | long | command | here
您必须将退出状态写入不同的文件描述符,否则会干扰发送到管道中下一个命令的输出。
【讨论】:
【参考方案2】:在 bash 中,您可以使用 PIPESTATUS
变量来做到这一点
echo "1" | grep 1
echo $PIPESTATUS[0] # returns 0
echo "1" | grep 2
echo $PIPESTATUS[0] # returns 0
echo "1" | grep 2
echo $PIPESTATUS[1] # returns 1
【讨论】:
最后一个命令不在管道内。$?
会更好,因为我想检索最后一个状态码,而不是第 n 个
@edi9999 把它放在命令里然后echo "1" | grep 2 | echo $PIPESTATUS[1]
是的,但如果我有三个命令而不是两个,它就行不通了:例如echo "1" | sed | grep 2 | echo $PIPESTATUS[1]
如果它们是当前管道之后的管道,也应该可以使用,如下所示:echo "1" | sed | grep 2 | echo $PIPESTATUS[1] | echo "3"
$PIPESTATUS 获取最后一个命令的结果,而不是当前命令的结果。测试它:echo "1" \n echo "ls" | grep "ls" | echo $PIPESTATUS[$#PIPESTATUS[@]-2]
返回-bash: PIPESTATUS: bad array subscript
以上是关于从最后一个管道(stdin)获取退出代码的主要内容,如果未能解决你的问题,请参考以下文章