簡體   English   中英

解決 ssh 不轉發信號的問題

[英]Work around ssh does not forward signal

如何解決ssh不轉發SIGTERM信號的問題?

我希望print-signal.py終止ssh root@localhost進程終止:

ssh root@localhost /root/print-signal.py

不幸的是,只有 ssh 進程本身獲得信號,而不是遠程命令( print-signal.py )。 遠程命令不會終止:-(

由於 openssh 不會將SIGTERM轉發到遠程命令,因此我正在尋找解決方法。

如果ssh root@localhost ... 終止,如何終止print-signal.py

這是一個后續問題: 通過 ssh 轉發 SIGTERM

免責聲明:下面的答案不是針對 SIGTERM,而是針對 SIGINT。 由於疏忽,這不是問題的答案。

您觀察到的問題是由於缺少 tty,它應該控制您嘗試運行的進程。 如果沒有可用的 tty,ssh 將無法向進程發送信號。 當您對ssh命令使用選項-t ,它將強制偽終端分配,這使得通過 ssh 發送信號成為可能:

ssh -t root@localhost /root/print-signal.py

man ssh -t強制偽終端分配。 這可用於在遠程機器上執行任意基於屏幕的程序,這非常有用,例如在實現菜單服務時。 多個-t選項強制 tty 分配,即使 ssh 沒有本地 tty。

Giles 在 unix.stackexchange 上給出了一個非常好的解釋。

在這里你可以看到它是如何工作的:

[terminal 1]% ssh server ./print_signal.py

上看到然后一個其他終端,其print_signal.py上運行PID=26992sshPID=26991無TTY( username@notty

[terminal 2]% ssh server ps -f                                                                                                                                                                                                            
UID        PID  PPID  C STIME TTY          TIME CMD
username 26991 26989  0 17:06 ?        00:00:00 sshd: username@notty
username 26992 26991  0 17:06 ?        00:00:00 python ./print_signal.py
username 27347 27345  0 17:07 ?        00:00:00 sshd: username@notty
username 27348 27347  0 17:07 ?        00:00:00 ps -f

使用 kill 或CTRL - C殺死 ssh 進程后,該進程仍處於活動狀態,但現在在/sbin/init ( PPID=1 ) 下運行

[terminal 2]% ssh server ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
username 26992     1  0 17:06 ?        00:00:00 python ./print_signal.py
username 27453 27451  0 17:08 ?        00:00:00 sshd: username@notty
username 27454 27453  5 17:08 ?        00:00:00 ps -f

使用-t標志可以很好地終止另一端的進程:

[terminal 1]% ssh -t server ./print_signal.py

上看到然后一個其他終端,其print_signal.py上運行PID=39277sshPID=39276綁定到一個tty( username@pts/10

[terminal 2]% ssh server ps -U username -f
UID        PID  PPID  C STIME TTY          TIME CMD
username 39276 39274  0 17:22 ?        00:00:00 sshd: username@pts/10
username 39277 39276  1 17:22 pts/10   00:00:00 python ./print_signal.py
username 39317 39314  0 17:22 ?        00:00:00 sshd: username@notty
username 39318 39317  5 17:22 ?        00:00:00 ps -U username -f

殺死ssh進程后

[terminal 1]% ssh -t server ./print_signal.py
My PID: 39277
^CCaught signal SIGINT (2), exiting.
Connection to server closed

該進程現在清楚地在另一台服務器上終止

[terminal 2]% ssh server ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
username 39768 39765  0 17:26 ?        00:00:00 sshd: username@notty
username 39769 39768  6 17:26 ?        00:00:00 ps -U username -f

我剛剛遇到了這個問題。 雖然我還沒有弄清楚確切的原因,但當ssh終止時會發生什么是您的進程重新父級為init 您可以告訴您的進程在其父進程死亡時請求一個信號,而不是使用prctl

如果您使用python-prctl ,請將以下內容盡早放入/root/print-signal.py

import signal
import prctl

prctl.set_pdeathsig(signal.SIGTERM)

如果父進程是 init 進程,您可以編寫一個終止的包裝器:

ssh root@localhost terminate-command-if-parent-is-lost print-signal.py

工具terminate-command-if-parent-is-lost需要這樣做:

啟動 argv 作為子print-signal.py (在本例中為print-signal.py )。 然后它每秒檢查其父 pid 的狀態(在 Python os.getppid() )。

如果 ppid 為 1(init 進程),則 print-signal.py 進程丟失了它的父進程。 這意味着“ssh root@localhost ...”已終止(或連接已關閉)。

現在terminate-command-if-parent-is-lost終止子進程。

如果 shell 支持某些內置變量( $! ),它可以輕松地幫助您解決此類問題。 這是一個基本的 shell 解決方案,通過很長的睡眠替換您的命令。

ssh server '(sleep 100000 & (MID=$!; A=n; while [ "$A" != y ];do echo "i am process $$ want kill "$MID" y/n?"; read A; done; kill -TERM $MID))'

命令中發送的腳本正在遠程主機上運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM