ssh 終止後,ssh 命令在其他系統上意外繼續
我正在執行以下命令,並監視另一個系統上的輸出文件:
ssh $ip_address 'for n in 1 2 3 4 5; do sleep 10; echo $n >>/tmp/count; done'
如果我使用或僅通過殺死我登錄的終端來終止 ssh 命令
^C
,我希望遠端命令也終止。但是這並沒有發生:不管怎樣,/tmp/count
得到所有的數字 1-5,並ps -ejH
顯示 shell 和它的sleep
子程序繼續執行。這是預期的行為,是否記錄在任何地方?我可以禁用它嗎?通過閱讀,我預計必須使用 nohup 顯式啟用這種行為,而不是讓它成為預設值。
我查看了 ssh 和 sshd 的手冊頁,但沒有發現任何明顯的東西,Google 指出了打開此行為的說明,而不是關閉它。
我正在執行 Red Hat Enterprise Linux 6.2,在兩個系統上都使用 root 登錄和 bash shell。
uther 的回答告訴你分配一個終端,但沒有解釋原因。原因不是特定於 ssh,而是信號生成和傳播的問題。我邀請您閱讀是什麼導致發送各種信號?了解更多背景資訊。
在遠端主機上,有兩個相關程序:
- 一個 ssh 守護程序 ( ) 的實例
sshd
,它將遠端程序的輸入和輸出中繼到本地終端;- 一個外殼,它正在執行該
for
循環。shell 可以在到達循環結束或遇到致命錯誤時自然死亡,或者在收到信號時自然死亡。問題是,為什麼外殼會收到信號?
如果遠端 shell 連接到
sshd
管道,這就是在命令行上指定命令時發生的情況,那麼如果退出並且 shell 嘗試寫入管道ssh
,它將死於SIGPIPE 。sshd
只要 shell 沒有寫入管道,它就不會收到 SIGPIPE。在這裡,shell 永遠不會向其標準輸出寫入任何內容,因此它可以永遠存在。您可以將
-t
選項傳遞給 ssh,告訴它模擬遠端端的終端並在此終端中執行指定的命令。然後,如果 SSH 客戶端消失,則sshd
關閉連接並退出,從而破壞終端。當終端設備離開時,其中執行的任何程序都會收到SIGHUP。因此,如果您終止 SSH 客戶端(使用kill
,或關閉客戶端正在執行的終端),遠端 shell 會被 SIGHUPped。如果您通過該
-t
選項,SSH 也會中繼SIGINT。如果按Ctrl
+C
,那麼遠端 shell 會收到一個 SIGINT。