使用Python将信号发送到远程进程

时间:2017-09-21 00:36:45

标签: python linux ssh process signals

有两台机器,其中一台有脚本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连接启动的远程进程?

1 个答案:

答案 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的远程会话。

我可以想出两种方法来做你想做的事情:

  1. 使用ssh参数而不是-tt调用-T。这将导致ssh为远程会话请求TTY。通过TTY运行远程进程将使其表现得像是以交互方式运行。杀死本地ssh进程应该导致远程进程接收SIGHUP。将 Ctrl - C 写入本地ssh进程的标准输入应该会导致远程进程收到SIGINT。

  2. 打开另一个ssh会话到远程主机,并使用killall或其他一些命令来指示您想要发出信号的进程。