如何解决ssh
未转发SIGTERM
信号的问题?
我希望print-signal.py
终止ssh root@localhost
进程终止:
ssh root@localhost /root/print-signal.py
不幸的是,只有ssh进程本身才能获得信号,而不是远程命令(print-signal.py
)。远程命令不会终止: - (
由于openssh没有将SIGTERM
转发给远程命令,我正在寻找解决办法。
如果print-signal.py
...终止,如何终止ssh root@localhost
这是一个后续问题:Forwarding SIGTERM over ssh
答案 0 :(得分:3)
免责声明:以下答案不适用于SIGTERM,而是适用于SIGINT。由于疏忽,这不是问题的答案。
您正在观察的问题是由于缺少tty而应该控制您尝试运行的进程。如果没有tty可用,则ssh无法将信号发送到进程。当您对-t
命令使用选项ssh
时,它将强制伪终端分配,这使得通过ssh发送信号成为可能:
ssh -t root@localhost /root/print-signal.py
man ssh
-t
强制伪终端分配。这可用于在远程机器上执行任意基于屏幕的程序,这可能非常有用,例如,实现菜单服务时。多个-t
选项强制tty分配,即使ssh没有本地tty。
Giles on unix.stackexchange给出了一个非常好的解释如何以及为什么。
在这里你可以看到它的工作原理:
[terminal 1]% ssh server ./print_signal.py
在另一个终端上,您看到print_signal.py
正在PID=26992
下ssh
下PID=26991
正在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
/sbin/init
使用kill或 CTRL - C 终止ssh进程后,该进程仍处于活动状态,但现在在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=39277
正在ssh
下PID=39276
下username@pts/10
绑定到tty([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
){} p>
[terminal 1]% ssh -t server ./print_signal.py
My PID: 39277
^CCaught signal SIGINT (2), exiting.
Connection to server closed
杀死ssh进程后
[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
现在,该流程已在其他服务器上明确终止
{
"apiVersion":"v1",
"meta":{
"pluginVersion":"v3.2.1",
"isExtruded":true
},
"error":{
"code":"Bad Request",
"status":400,
"diagnosticMessage":"invalid barcode type"
}
}
答案 1 :(得分:1)
我刚刚遇到了这个问题。虽然我还没有找到确切的原因,但是当ssh终止时会发生什么,那就是您的进程已重新初始化为init。您可以告诉进程在父进程去世时询问信号,而不要使用prctl。
如果您使用python-prctl,请在/root/print-signal.py
上放置以下内容
import signal
import prctl
prctl.setpdeathsig(signal.SIGTERM)
答案 2 :(得分:0)
您可以编写一个包装器,如果父进程是init进程,它将终止:
ssh root@localhost terminate-command-if-parent-is-lost print-signal.py
工具terminate-command-if-parent-is-lost
需要执行此操作:
启动argv作为子进程(在此示例中为print-signal.py
)。然后它每秒检查其父pid的状态(在Python os.getppid()
中)。
如果ppid为1(init进程),则print-signal.py进程已丢失其父进程。这意味着" ssh root @ localhost ..."被终止(或连接已关闭)。
现在terminate-command-if-parent-is-lost
终止子流程。
答案 3 :(得分:0)
如果它支持一些内置变量($!),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))'
该命令中发送的脚本正在远程主机上运行。