2015-04-07 89 views
0

我正在通过ssh在bash中执行管道命令链。如果任何一个命令失败,我想退出。如果在整个管道完成执行之后出口发生,那么可以。如果其中一个命令失败,我只想为管道分配一个总体“失败”状态。通过ssh执行的管道命令的退出状态

一个最小的例子是:

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

我想,如果管道中的任何一个命令失败,失败退出。如果我在本地执行命令链,我可以使用${PIPESTATUS[0]}拔出链中任何命令的退出状态。但通过SSH,我得到了最后一个命令的退出状态。即如果CMD1失败,并且CMD2成功,则本地主机上的$?将给我0。如果CMD1失败,我怎样才能将整体失败状态分配给管线?

+0

关于“over ssh”没有任何关于这个问题的重要部分 - 你可以取出SSH并仍然有同样的问题。考虑到在下一次询问之前将其作为找到问题核心的一部分。 –

+0

@CharlesDuffy正如我的问题所述,我能够在本地运行时运行'PIPESTATUS'来截取链中任何命令的退出状态。据我所知,我无法使用'PIPESTATUS'来运行'ssh'并获得'全局'退出状态。因此,额外的规格。 – RDK

+0

'PIPESTATUS'不会传输到本地shell,但可以在远程端运行它。即:'ssh“$ host”bash <<<'CMD | CMD2;退出$((PIPESTATUS [0] | $ {PIPESTATUS [1]}))'' –

回答

2

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

如果设置,管道的返回值是最后一个(最右边)的命令的退出,如果该值以非零状态,或零管道中的所有命令成功退出。该选项默认是禁用的。

尝试,例如,

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

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


在另一方面,如果你的远程用户的默认外壳是zsh,像我这样做,你应该使用setopt pipe_fail代替。请注意,这是对zsh的一个相对较新的补充。我无法确定它何时添加,但我知道它适用于5.0.5而不是5.0.2。

+0

我以前认为在执行bash中的'ssh'命令时,我误解了问题的第一行,从中我无法推断出您的远程shell。对于那个很抱歉。无论如何,我相信提供有关'zsh'的更多信息没有任何问题。 – 4ae1e1

+0

我的shell是本地打击和bash远程的。 'set -o pipefail'完全符合我的想法。 – RDK