Ich möchte in der Lage sein, über ssh Signale zu senden (SIGINT ist das wichtigste).
Dieser Befehl:
ssh server "sleep 1000;echo f" > foo
wird den Schlafmodus auf dem Server starten und nach 1000 Sekunden 'f \ n' in die Datei foo auf meinem lokalen Computer einfügen. Wenn ich STRG-C drücke (dh SIGINT an ssh senden), wird ssh beendet, der Schlaf auf dem Remote-Server wird jedoch nicht beendet. Ich möchte, dass es den Schlaf auf dem Remote-Server beendet.
Also habe ich versucht:
ssh server -t "sleep 1000;echo f" > foo
Aber wenn stdin kein Terminal ist, bekomme ich diese Fehlermeldung:
Pseudo-terminal will not be allocated because stdin is not a terminal.
und dann wird SIGINT immer noch nicht weitergeleitet.
Also habe ich versucht:
ssh server -t -t "sleep 1000;echo f" > output
Aber dann ist die Ausgabe in foo nicht 'f \ n', sondern 'f \ r \ n', was in meiner Situation katastrophal ist (da es sich bei meiner Ausgabe um Binärdaten handelt).
In der obigen Beschreibung verwende ich "sleep 1000; echo f", aber in Wirklichkeit wird dies vom Benutzer bereitgestellt und kann daher alles enthalten. Wenn wir es jedoch für "sleep 1000; echo f" zum Laufen bringen können, können wir es höchstwahrscheinlich für alle realistischen Situationen zum Laufen bringen.
Es ist mir wirklich egal, ob ich ein Pseudo-Terminal am anderen Ende bekomme, aber ich konnte keinen anderen Weg finden, um ssh dazu zu bringen, mein SIGINT weiterzuleiten.
Gibt es eine andere Art und Weise?
Bearbeiten:
Der Benutzer könnte Befehle geben, die Binärdaten aus stdin lesen, wie zum Beispiel:
seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo
Der Benutzer kann Befehle geben, die CPU-intensiv sind, wie zum Beispiel:
ssh server "timeout 1000 burnP6"
Edit2:
Die Version, die für mich zu funktionieren scheint, ist:
your_preprocessing |
uuencode a | ssh -tt -oLogLevel=quiet server "stty isig -echoctl -echo ; uudecode -o - |
your_command |
uuencode a" | uudecode -o - |
your_postprocessing
Vielen Dank an digital_infinity für den Hinweis in die richtige Richtung.
ssh
muss komplizierter sein als das, was Sie als Beispiele zeigen, weil Sie das gewünschte Verhalten durch eine einfache Neuanordnung erreichen können:sleep 1000 && ssh server "echo f" > foo
(Das muss&&
nicht;
so sein, dass das Tötensleep
diessh
Ausführung des Befehls verhindert .) Wenn ich Bitte machen Sie Ihre Beispiele repräsentativer für Ihre tatsächliche Verwendung, damit eine bessere Antwort gegeben werden kann.Antworten:
Kurze Antwort:
und beenden Sie das Programm mit STRG + N.
Lange Erklärung:
stty
Option verwendenintr
, um den Server oder das lokale Interrupt-Zeichen so zu ändern , dass sie nicht miteinander kollidieren. Im obigen Befehl habe ich das Server-Interrupt-Zeichen in STRG + N geändert. Sie können Ihr lokales Interrupt-Zeichen ändern und das des Servers unverändert lassen.stty -echoctl
.stty isig
SIGINT
Signal tatsächlichtrap '/bin/true' SIGINT
mit einer leeren Anweisung ab. Ohne die Falle haben Sie kein stdout nach SIGINT-Signal an Ihrem Ende.quelle
seq 1000 | gzip | ssh -tt dell-test "zcat|bzip2" | bzcat > foo
auch nicht funktioniert. Damit dieser Befehl funktioniert, müssen wir ihn entfernen-tt
. Die Zuordnung der Pseudo-Terminals wird also wahrscheinlich von stdin(sleep 1; seq 1000 ) | gzip | uuencode bin | ssh -tt dell-test "stty isig intr ^N -echoctl -echo ; trap '/bin/true' SIGINT; sleep 1; uudecode -o /dev/stdout | zcat |bzip2 | uuencode bin2 " | uudecode -o /dev/stdout | bzcat >foo
. Obwohl die Interrupt - Zeichen funktioniert nicht - brauchen wir eine Übertragungsmethode für die Interrupt - Zeichen während stdin ist besetzt .Ich habe alle Lösungen ausprobiert und dies war das Beste:
/programming/3235180/starting-a-process-over-ssh-using-bash-and-then-killing-it-on-sigint/25882610#25882610
quelle
sleep
Vorgang nicht, falls die Verbindung unterbrochen wird.sleep
, nicht wahr? Ich habe einigedate >> /tmp/killed
nach dem hinzugefügtcat
, aber es wurde nicht ausgelöst. Ist eine Auszeit erforderlich? Ich benutze Zsh normalerweise, habe es aber auch mit bash als Remote-Login-Shell getestet.-o ServerAliveInterval=3 -o ServerAliveCountMax=2
ermöglicht es, es schnell zu erkennen, aber gibt es etwas für die Server-Seite?Ich denke, Sie könnten die PID des Prozesses finden, den Sie auf dem Server ausführen, und ein Signal mit einem anderen
ssh
Befehl senden (wie folgt:)ssh server "kill -2 PID"
.Ich verwende diese Methode zum Senden von Rekonfigurationssignalen an Anwendungen, die auf einem anderen Computer ausgeführt werden (meine Anwendungen erfassen SIGUSR1 und lesen eine Konfigurationsdatei). In meinem Fall ist es einfach, eine PID zu finden, da ich eindeutige Prozessnamen habe und die PID durch Senden einer
ps
Anfrage über finden kannssh
.quelle
Die Lösung entwickelte sich zu http://www.gnu.org/software/parallel/parallel_design.html#Remote-Ctrl-C-and-standard-error-stderr
quelle
----- command.sh
----- am lokalen Terminal
quelle