包含 while 迴圈的 PuTTY 遠端指令

包含 while 迴圈的 PuTTY 遠端指令

我正在嘗試自動執行透過 SSH 連接到遠端伺服器來執行的幾個常見任務。為此,我在幾個已儲存的會話中使用 PuTTY 及其「遠端命令」選項(連接 > SSH)。我的遠端命令如下所示:

~/scripts/test; $SHELL -l

每個已儲存的會話執行的腳本都不同,並執行不同的任務。$SHELL -l腳本執行完畢後,保持 PuTTY 會話處於活動狀態。

所有這一切對於我正在運行的大多數腳本來說都非常有效。但是,我有一個使用 while 迴圈來執行一系列命令,直到用 Ctrl+C 終止為止。腳本啟動正常,但 PuTTY shell 在終止後不會保持活動。$SHELL -l似乎沒有被執行。

具有此行為的範例腳本如下:

while true; do
echo "."
sleep 2
done

以下工作正常手動執行,我看到第二個命令的預期輸出:

~/scripts/test; echo "done"

但是,PuTTY“遠端命令”的第二個命令不執行。事實上,如果我更改遠端命令以包含echo,它就不會顯示。

~/scripts/test; echo "done"; $SHELL -l

所以我想我的問題是:為什麼清單中的第二個命令不是由遠端命令執行,而是在手動執行時執行?更重要的是,我能做些什麼呢?

如果相關的話,我正在 Ubuntu 14.04 上運行 PuTTY。

答案1

當您運行puttyssh(我認為在這種情況下沒有任何區別)在遠端系統上運行命令時,遠端 ssh 伺服器會將該命令作為 shell 命令運行:

/bin/bash -c '~/scripts/test; $SHELL -l'

因此,您bash在遠端系統上有一個執行此管道的實例。您還有另一個bash實例,由第一個實例啟動,執行此「測試」腳本。

當您鍵入 Control-C 時,請將該putty字元傳送到遠端系統,並由您的 TTY 將其解釋為中斷字元。這會導致向附加到 TTY 的進程發送 SIGINT(中斷訊號)。這會中斷這兩個 shell 進程,導致它們都退出。您希望父 shell 實例忽略 SIGINT。

忽略 SIGINT 的 bash 指令是:

trap "" INT

因此,要停用管道的 SIGINT,您可以將原始命令變更為:

trap '' INT; ~/scripts/test; $SHELL -l

但這也會停用子程序的 SIGINT,這將使「測試」腳本不受 Ctrl-C 的影響。因此,您需要為測試腳本重新啟用 SIGINT。其命令為:

trap INT

您可以將該行新增至測試腳本本身,也可以將其新增至管道:

trap '' INT; ( trap INT; ~/scripts/test ); $SHELL -l

現在,當您按下 Ctrl-C 時,您應該中斷「測試」進程,而不是正在執行命令管道的父進程。

您可以在不使用 putty 或 ssh 的情況下對此進行測試。只需執行這些命令並嘗試在「睡眠」執行時按 Ctrl-C:

bash -c 'sleep 15; echo foo'                  # Ctrl-C kills sleep; doesn't print "foo"
bash -c 'trap "" INT ; sleep 15; echo foo'    # Ctrl-C has no effect
bash -c 'trap "" INT; ( trap INT; sleep 15 ); echo foo'    # Kills sleep, prints "foo"

答案2

putty 遠端命令的 ctrl+c 實際上會中斷 ssh 會話,因此應該預期它不會執行剩餘的遠端命令。如果您的目標只是讓會話繼續保持活動狀態,那麼您的無限循環就足夠了。

相關內容