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

使用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的远程会话。

我能想到的两种方法可以做到你想要什么:

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

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