通过 ssh 执行的管道命令的退出状态

Exit status of a piped command executed over ssh

我正在通过 ssh 在 bash 中执行管道命令链。如果任何一个命令失败,我想退出。如果退出发生在整个管道执行完之后,那也没关系。如果其中一个命令失败,我只想为管道分配一个总体 'fail' 状态。

一个最小的例子是:

ssh $REMOTE_HOST "CMD1 | CMD2" >> file.txt

如果管道中的任何一个命令失败,我想失败退出。如果我在本地执行命令链,我可以使用 ${PIPESTATUS[0]} 来提取链中任何命令的退出状态。但是通过 ssh,我得到了最后一个命令的退出状态。 IE。如果 CMD1 失败而 CMD2 成功,本地主机上的 $? 会给我 0。如果 CMD1 失败,我如何为管道分配整体失败状态?

由于这个问题被标记为 bash,我假设您的远程用户的默认 shell 是 Bash。在这种情况下,您应该设置 the pipefail optionset -o pipefail。根据上面链接的 Bash 参考手册:

If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully. This option is disabled by default.

尝试,例如,

ssh $REMOTE_HOST 'false | true'
ssh $REMOTE_HOST 'set -o pipefail; false | true'

查看 ssh 命令退出状态的差异。


另一方面,如果您的远程用户的默认 shell 是 zsh,您应该像我一样使用 setopt pipe_fail。请注意,这是对 zsh 的一个相对较新的补充。我不能确定它是何时添加的,但我知道它适用于 5.0.5 但不适用于 5.0.2。