【问题标题】:Send signals to remote process with Python使用 Python 向远程进程发送信号
【发布时间】:2017-09-21 00:36:44
【问题描述】:

有两台机器,其中一台有一个脚本wait_for_signal.sh,第二台有一个名为controller.py的脚本。每个脚本的代码如下所示。

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 = 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 连接启动的远程进程?

【问题讨论】:

    标签: python linux ssh process signals


    【解决方案1】:

    您正在使用 -T 选项调用 ssh,这意味着它不会为远程会话分配 PTY(伪 TTY)。在这种情况下,无法通过 ssh 会话向远程进程发送信号。

    SSH 协议有一个message to send a signal to the remote process。但是,您可能将 OpenSSH 用于客户端或服务器或两者,据我所知,OpenSSH 没有实现信号消息。所以 OpenSSH 客户端无法发送消息,OpenSSH 服务器也不会对其进行操作。

    有一个SSH extension to send a "break" message受 OpenSSH 支持。在交互式会话中,OpenSSH 客户端有一个escape sequence,您可以键入它来向服务器发送中断。 OpenSSH 服务器通过向远程会话的 PTY 发送中断来处理中断消息,而 unix PTY 通常会将中断视为 SIGINT。但是,从根本上讲,中断是一个 TTY 概念,这些都不适用于没有 PTY 的远程会话。

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 2015-05-11
      • 1970-01-01
      • 2016-03-21
      • 2017-01-20
      • 1970-01-01
      • 1970-01-01
      • 2017-07-11
      • 2013-07-30
      相关资源
      最近更新 更多