使用Python将信号发送到远程进程
有两台机器,其中一台具有脚本wait_for_signal.sh
,另一台具有名为controller.py
的脚本。每个脚本的代码如下所示。使用Python将信号发送到远程进程
controller.py
的用途是生成一个子进程,该子进程通过ssh
调用wait_for_signal.sh
脚本。当控制器需要退出时,它需要向运行wait_for_signal.sh
的远程进程发送一个中断。
wait_for_signal.sh
#!/bin/bash
trap 'break' SIGINT
trap 'break' SIGHUP
echo "Start loop"
while true; do
sleep 1
done
echo "Script done"
controller.py
import os
import signal
import subprocess
remote_machine = [email protected]
remote_path = path/to/script/
remote_proc = subprocess.Popen(['ssh', '-T', remote_machine,
'./' + remote_path + 'wait_for_signal.sh'],
shell=False, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# do other stuff
os.kill(remote_proc.pid, signal.SIGINT)
目前,信号发送,是该开始在本地机器上的SSH连接的过程,而不是远程机。这导致本地进程停止,但远程进程继续执行。
ssh如何工作以及它在停止时发送给远程机器的信号类型?如何将适当的信号发送到由ssh连接启动的远程进程?
您使用-T
选项调用ssh
,这意味着它不会为远程会话分配PTY(伪TTY)。在这种情况下,无法通过该ssh会话发信号通知远程进程。
SSH协议有一个message to send a signal to the remote process。但是,您可能使用OpenSSH作为客户端或服务器,或者同时使用OpenSSH,并且据我所知,OpenSSH不会执行信号消息。所以OpenSSH客户端不能发送消息,并且OpenSSH服务器不会对其执行操作。
有一个SSH extension to send a "break" message其中是由OpenSSH支持。在交互式会话中,OpenSSH客户端有一个escape sequence,您可以键入该值以向服务器发送中断。 OpenSSH服务器通过向远程会话的PTY发送中断来处理中断消息,并且unix PTYs通常会将中断视为SIGINT。然而,休息从根本上说是TTY的概念,并且这些都不适用于没有PTY的远程会话。
我能想到的两种方法可以做到你想要什么:
调用
ssh
与-tt
参数,而不是-T
。这将导致ssh为远程会话请求一个TTY。通过TTY运行远程进程将使它像交互式运行一样。杀死本地ssh进程应该会导致远程进程接收SIGHUP。写一个Ctrl - C到本地ssh进程的标准输入应该会导致远程进程接收到一个SIGINT。打开另一个ssh会话到远程主机,并使用
killall
或其他命令来发信号通知您想要发送的进程。