有两台机器,其中一台有脚本wait_for_signal.sh
,第二台机器有一个名为controller.py
的脚本。每个脚本的代码如下所示。
controller.py
的目的是产生一个通过wait_for_signal.sh
调用ssh
脚本的子进程。当控制器需要退出时,它需要向运行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 = user@ip
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如何工作以及它向远程机器发送什么类型的信号?如何将相应的信号发送到由ssh连接启动的远程进程?
答案 0 :(得分:1)
您正在使用ssh
选项调用-T
,这意味着它不会为远程会话分配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客户端具有escape sequence,您可以键入该值以向服务器发送中断。 OpenSSH服务器通过向远程会话的PTY发送中断来处理中断消息,并且unix PTY通常将中断视为SIGINT。但是,休息时间基本上是一个TTY概念,并且这些都不适用于没有PTY的远程会话。
我可以想出两种方法来做你想做的事情:
使用ssh
参数而不是-tt
调用-T
。这将导致ssh为远程会话请求TTY。通过TTY运行远程进程将使其表现得像是以交互方式运行。杀死本地ssh进程应该导致远程进程接收SIGHUP。将 Ctrl - C 写入本地ssh进程的标准输入应该会导致远程进程收到SIGINT。
打开另一个ssh会话到远程主机,并使用killall
或其他一些命令来指示您想要发出信号的进程。