2015-04-07 88 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