Kann ich den exit-code eines Befehls in einer subshell ausgeführt, die über ssh?
Ich versuche, Paramiko zu schreiben, ein deployment-Skript, und ich habe Probleme mit exit-Code aus dem Befehle, die ich ausführen. Ich benutze ähnlichen code wie den in diese Antwort, aber es ist ein wenig komplizierter. Im Grunde genommen, aus unserer dev-Boxen wir uns durch einen Sprung server, und von dort aus zu einer Reihe von Maschinen in der Produktion. Dort angekommen haben wir die Umstellung auf ein system-user (sudo su - systemuser) und dann können wir Befehle ausführen.
Das problem ist, dass ich es verstehe ich habe 3 Unterschalen - der ssh-Sitzung, die verschachtelte ssh-Befehl und dann die su subshell. Ich kann nicht Paramiko, um mir wieder der exit-code des Kommandos in das innere subshell - ich denke, der exit-code wird es irgendwann wieder werden, dass der ssh-Befehl. Ich vermute, das problem ist eigentlich nicht spezifisch für Paramiko - nicht das SSH-Protokoll unterstützen auch diese Art der Nutzung?
Ich bin derzeit immer ausführen:
(my command); echo "Process terminated with exit code $?"
und dann analysieren diese auf dem client, aber es ist ziemlich hässlich - gibt es einen schöneren Weg?
InformationsquelleAutor Colin | 2011-03-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, und Nein.
Den exit-status immer zurückgegeben, aber es kann nicht sein, von wo aus Sie denken. Sobald Sie den Anruf
invoke_shell()
Ihre remote-Prozess ist eine Schale, wahrscheinlich bash. Dieexit_status
Sie erhalten werden die, die aus dieser Schale, nicht allen Prozessen, lief es. Paramiko (oder ssh-implementation ab), jemals zurückzukehren, der exit-status des Kommandos, weil der exit-Status sind nie draußen gesehen, dass remote-shell. Es ist an Ihnen, zu entscheiden, was Ihre exit-status sein sollte, und beenden Sie die shell mitexit $EXIT_STATUS
(oftexit $?
ist genug)Wenn Sie brechen Ihre Befehle, oder wickeln Sie Sie in ein Skript, dann verwenden Sie die
exec_command()
Methode, haben Sie Zugang zu den richtigen exit-status direkt.Alternativ können Sie den shell-Befehl
exec
in der remote-shell und der shell-Prozess wird ersetzt durch den Befehl aufgerufen durch exec und seinen exit-status zurückgegeben werden.Alle drei dieser Methoden wird die
channel.exit_status
- Attribut wie erwartet.invoke_shell()
wird, will ich führen verschiedene Befehle auf dem server ohne Wiederherstellung der Verbindung. Ich muss durch eine jump-box, also von Paramiko ich benutzeconnect()
(Sprung Kasten)invoke_shell()
dann ausführenssh <server>
. Dort habe ich wechseln müssen, um einen system-Benutzer (sudo su - <user>
), dann möchte ich in der Lage sein, um die Ausführung verschiedener Befehle, ohne erneut alles von oben, aber immer noch abrufen der return-codes. Ist das möglich?Ja, durch die Techniken, die ich oben zeige. Es ist bis zu Ihnen, zu übertragen, die Rückkehr-codes, die Sie möchten, sichern Sie die Kette, entweder durch
exit
'ing die Schale mit dem richtigen status, oder durchexec
'ing den Befehl, den Sie möchten direkt.aber das ist nur mir erlaubt, zurückzukehren, der exit-code von einem einzigen Befehl pro Sitzung (seit
exec
ersetzt den aktuellen Prozess). Ich würde dann erneut eine Verbindung zwischen jedem Befehl, richtig?ja, man bekommt nur die last-exit-code, der eine Rückgabe durch die shell/remote-Prozess. Das ist nur, wie eine shell arbeitet, und hat nichts zu tun mit ssh. Da bist du auf der Suche für exit_status, ich nehme an, du bist scripting mit diesen Befehlen; warum nicht senden Sie die Logik, um die remote-Maschine in einem python/shell-Skript, wo haben Sie direkten Zugang zu den Befehlen? Ansonsten brechen die Befehle und die Verwendung des ssh-Kanal, wie ein RPC-Mechanismus, wo Sie effektiv zu ignorieren, die "shell" - Teil.
Ich werde versuchen diese Optionen - vielen Dank!
InformationsquelleAutor JimB
Ich habe da ein problem, wo der man-page für 'ssh' sagt, es gibt den exit-code des Prozesses, es läuft, aber ich kann nicht scheinen, um es zu geben ein nicht-null-Fehler-Codes. Von der ssh Manpage:
Die nicht scheint, um wahr zu sein.
Aber ich würde versuchen, so etwas wie dieses, und sehen, was passiert auf Ihrem system.
Wenn ich einen ähnlichen Befehl lokal, bash gibt einen exit-code.
Den Anführungszeichen entfernt werden, bevor ssh scheint die Befehle jedoch.
Also lasst uns versuchen, mehr Zitate.
Bingo. Die "exit 3" war, sich in "exit", gefolgt von einem Wort ignoriert
auf der bash-Kommandozeile. Also bash ausgeführt wurde, den Befehl "exit".
Leider nicht für mich, ich denke, diese ganze Antwort ist ein Exkurs
aus den original-Fragen und enthält nicht genügend Verdienst als
eine Frage, die in seinem eigenen Recht. Also danke an alle für die Hilfe
Antwort von sekundären Fragestellung (nicht im Zusammenhang mit der ursprünglichen Frage).
Ich habe gerade versucht dies mit einem Befehl, der direkt einen Fehlercode zurückgibt, und das funktioniert richtig:
ssh localhost "ls blarg"; echo $?
richtig einen Fehlercode zurückgibt. Ich denke, dass in deinem Beispiel dieexit
subshell gibt 3 bash, aber bash gibt 0 zurück (weil es endet richtig).Ich bekomme die gleiche:
ssh localhost bash -c "exit 3"
0 zurück.echo 'exit 3' | ssh localhost bash
3 gibt. Überraschend in dieser gibt auch 0:ssh localhost bash -eu -c "exit 3"
InformationsquelleAutor Chris Quenelle