Frage Verwenden von SSH, um einen Prozess remote zu starten


Ich habe ein Skript geschrieben, das ich benutze, um einen neuen Dienst an mehrere Rechner unter meiner Kontrolle zu übertragen und zu deployen, und um den Prozess auszuführen, benutze ich ssh, um den Prozess remote zu starten. Unglücklicherweise scheint der SSH-Befehl nie zurückzukehren, wenn ich SSH benutze, um den Prozess zu starten, wodurch das Skript zum Stillstand kommt.

Der Befehl wird wie folgt angegeben: ssh $ user @ $ host "/ root / command &". Immer, wenn ich einfache Befehle wie ps oder who ausführe, kehrt der SSH-Befehl sofort zurück. Wenn ich versuche, den Prozess zu starten, kehrt er jedoch nicht zurück. Ich habe versucht, meinen Prozess in ein einfaches Bash-Skript zu verpacken, das den Prozess startet und dann beendet, jedoch hängt dies auch den SSH-Befehl (auch wenn das Bash-Skript eine Erfolgsmeldung ausgibt und normal beendet wird).

Hat jemand einen Einblick in das, was dieses Verhalten verursacht, und wie ich den SSH-Befehl erhalten kann, sobald der Prozess gestartet wurde?

Danke für deine Einsichten!


18
2017-07-06 15:21


Ursprung


Veröffentlichen Sie die genaue Befehlszeile, die Sie verwenden ... Passwörter / Benutzernamen / IPs auslassen - Joseph Kern
SSH $ SSH_USER @ $ HOST_ADDR "/ root / AppName &" - rmrobins
Ich sollte erwähnen, dass ich SSH-Schlüssel eingerichtet habe, so dass es nicht notwendig ist, Passwörter zu verwenden, um Befehle auf den Remote-Systemen auszuführen. - rmrobins
@rmrobins, ein sehr guter Schritt - Einstellung Public Key Auth. - nik


Antworten:


SSH verbindet stdin, stdout und stderr der Remote-Shell mit Ihrem lokalen Terminal, sodass Sie mit dem Befehl interagieren können, der auf der Remote-Seite ausgeführt wird.

Als Nebeneffekt wird es weiterlaufen, bis diese Verbindungen geschlossen wurden, was nur passiert, wenn der Remote-Befehl und alle seine untergeordneten (!) Beendet sind (weil die Kinder, die "&" starten, von ihnen std * erben) Elternprozess und halten Sie es offen).

Sie müssen also etwas wie

ssh user@host "/script/to/run < /dev/null > /tmp/mylogfile 2>&1 &"

Die <,> und 2> & 1 leiten stdin / stdout / stderr von Ihrem Terminal weg. Das "&" bringt dann Ihr Skript in den Hintergrund. In der Produktion würden Sie natürlich stdin / err in eine geeignete Logdatei umleiten.

Sehen

http://osdir.com/ml/network.openssh.general/2006-05/msg00017.html

Bearbeiten:

Habe gerade herausgefunden, dass die < /dev/null oben ist nicht notwendig (aber umleiten stdout / err ist). Keine Ahnung warum ...


28
2017-07-06 15:44



Danke, das ist genau das, wonach ich gesucht habe - mir ist nicht in den Sinn gekommen, dass der Prozess die Std * erben würde, selbst wenn er & im Hintergrund gestartet wird. - rmrobins
+1! Funktioniert bei mir. Und Sie können die Ausgabe auch durch Echo der Protokolldatei drucken: ssh user@host "/script/to/run > /tmp/ssh.stdout 2>&1 && cat /tmp/ssh.stdout && rm -f /tmp/ssh.stdout" - Fishdrowned


Du könntest es versuchen Nohup. Man nohup für weitere Details.

ssh host "nohup script &"

Wenn Sie die Ausgabe auf dem Remote-Computer beibehalten möchten, Hier ist eine Variante.

ssh user@host 'export REMOTE=myname; nice nohup ./my-restart >
logfile.log 2>&1 &'

5
2017-07-06 16:15





Eine andere Alternative wäre es, ein Abgebildetes anzuzünden screen(1), so etwas wie:

ssh -l user host "screen -d -m mycommand"

Dies startet einen getrennten Bildschirm (der alle Interaktionen in ihm erfasst) und kehrt dann sofort zurück und beendet die SSH-Sitzung.

Mit etwas mehr Einfallsreichtum können Sie auf diese Weise relativ komplexe Remote-Befehlsaufrufe lösen.


5
2017-07-06 19:53





 -f      Requests ssh to go to background just before command execution.
         This is useful if ssh is going to ask for passwords or
         passphrases, but the user wants it in the background.  This
         implies -n.  The recommended way to start X11 programs at a
         remote site is with something like ssh -f host xterm.

         If the ExitOnForwardFailure configuration option is set to “yes”,
         then a client started with -f will wait for all remote port for‐
         wards to be successfully established before placing itself in the
         background.

4
2017-07-06 15:30



Das Problem mit dieser Methode ist, dass der SSH-Befehl nicht wirklich beendet wird. Er wird einfach im Hintergrund versteckt, so dass der Host, der das Skript ausführt, eine große Anzahl von SSH-Befehlen im Hintergrund hat, die niemals zurückkehren, weil die SSH-Befehle niemals zurückkommen. dh das Grundproblem, das ich lösen möchte) - rmrobins


Ich denke, der richtige Weg wäre

ssh user@host exec script.sh &

-1
2017-07-06 15:32



Nein, das funktioniert nicht für mich. Warum sollte es? - sleske
Ich habe den Hintergrund Push über ssh nicht benutzt, habe versucht ohne einen Begriff zur Hand zu haben. mein Fehler. - nik