2017-09-21 3 views
0

Es gibt zwei Maschinen, wobei eine über ein Skript wait_for_signal.sh verfügt und die zweite ein Skript mit dem Namen controller.py. Der Code jedes Skripts wird unten angezeigt.Senden von Signalen an Remote-Prozess mit Python

Der Zweck der controller.py ist, einen Subprozess zu spawnen, der das Skript wait_for_signal.sh über ssh aufruft. Wenn der Controller beendet werden muss, muss er einen Interrupt an den Remote-Prozess senden, der wait_for_signal.sh ausführt.

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) 

Derzeit ist das Signal senden, um den Prozess, den die SSH-Verbindung auf dem lokalen Computer und nicht die Fernbedienung gestartet Maschine. Dies führt dazu, dass der lokale Prozess gestoppt wird, der Remote-Prozess jedoch weiterhin ausgeführt wird.

Wie funktioniert ssh und welche Art von Signalen wird an den entfernten Rechner gesendet, wenn er gestoppt wird? Wie kann ich das entsprechende Signal an den Remote-Prozess senden, der von der SSH-Verbindung gestartet wurde?

Antwort

1

Sie rufen ssh mit der Option -T auf, was bedeutet, dass kein PTY (Pseudo-TTY) für die Remotesitzung zugewiesen wird. In diesem Fall gibt es keine Möglichkeit, den Remote-Prozess über diese SSH-Sitzung zu signalisieren.

Das SSH-Protokoll hat eine message to send a signal to the remote process. Allerdings verwenden Sie wahrscheinlich OpenSSH für den Client oder den Server oder für beide, und soweit ich das beurteilen kann, implementiert OpenSSH die Signalnachricht nicht. Daher kann der OpenSSH-Client die Nachricht nicht senden und der OpenSSH-Server wird nicht darauf reagieren.

Es gibt eine SSH extension to send a "break" message welche ist unterstützt von OpenSSH. In einer interaktiven Sitzung verfügt der OpenSSH-Client über eine escape sequence, die Sie eingeben können, um eine Unterbrechung an den Server zu senden. Der OpenSSH-Server verarbeitet Unterbrechungsnachrichten, indem er eine Unterbrechung an den PTY für die Remotesitzung sendet, und Unix-PTYs behandeln eine Unterbrechung normalerweise als ein SIGINT. Breaks sind jedoch grundsätzlich ein TTY-Konzept und nichts davon wird für Remote-Sitzungen funktionieren, die kein PTY haben.

Ich denke an zwei Möglichkeiten zu tun, was Sie wollen:

  1. Invoke ssh mit dem -tt Parameter statt -T. Dies veranlasst ssh, ein TTY für die Remote-Sitzung anzufordern. Wenn Sie den Remote-Prozess über ein TTY ausführen, verhält es sich so, als ob es interaktiv läuft. Das Beenden des lokalen SSH-Prozesses sollte dazu führen, dass der Remote-Prozess eine SIGHUP erhält. Schreiben einer Ctrl - C an die Standardeingabe des lokalen ssh-Prozesses sollte dazu führen, dass der remote Prozess ein SIGINT erhält.

  2. Öffnen Sie eine weitere SSH-Sitzung zum Remote-Host und verwenden Sie killall oder einen anderen Befehl, um den Prozess zu signalisieren, den Sie signalisieren möchten.

Verwandte Themen