Ihre Annahme, dass es sich ssh
selbst handelt, der den Exit-Status 255 zurückgibt, ist korrekt. In der ssh
Manpage heißt es:
ssh wird mit dem Exit-Status des Remote-Befehls oder mit 255 beendet, wenn ein Fehler aufgetreten ist.
Wenn Sie einfach ausführen würden ssh pi@10.20.0.10 "pkill -f asdf"
, würden Sie höchstwahrscheinlich einen Beendigungsstatus von erhalten 1
, der dem pkill
Status für " Keine Prozesse gefunden " entspricht.
Die Herausforderung besteht darin, zu verstehen, warum bei der Ausführung von SSH ein Fehler auftritt
ssh pi@10.20.0.10 "pkill -f asdf || true"
SSH-Fernbefehle
Der SSH-Server startet eine Shell zum Ausführen von Remote-Befehlen. Hier ist ein Beispiel dafür in Aktion:
$ ssh server "ps -elf | tail -5"
4 S root 35323 1024 12 80 0 - 43170 poll_s 12:01 ? 00:00:00 sshd: anthony [priv]
5 S anthony 35329 35323 0 80 0 - 43170 poll_s 12:01 ? 00:00:00 sshd: anthony@notty
0 S anthony 35330 35329 0 80 0 - 28283 do_wai 12:01 ? 00:00:00 bash -c ps -elf | tail -5
0 R anthony 35341 35330 0 80 0 - 40340 - 12:01 ? 00:00:00 ps -elf
0 S anthony 35342 35330 0 80 0 - 26985 pipe_w 12:01 ? 00:00:00 tail -5
Beachten Sie, dass die Standard-Shell ist bash
und dass der Remote-Befehl kein einfacher Befehl, sondern eine Pipeline ist , „eine Folge von einem oder mehreren Befehlen, die vom Steueroperator getrennt werden|
".
Die Bash - Shell klug genug , um zu erkennen , dass , wenn der Befehl von der an sie übergeben werden -c
Option ist ein einfacher Befehl , es durch nicht wirklich Forking einen neuen Prozess zu optimieren, das heißt, es direkt exec
s den einfachen Befehl statt durch den zusätzlichen Schritt des Gehens von fork
ing , bevor es exec
s. Hier ist ein Beispiel dafür, was passiert, wenn Sie einen einfachen Remote-Befehl ausführen ( ps -elf
in diesem Fall):
$ ssh server "ps -elf" | tail -5
1 S root 34740 2 0 80 0 - 0 worker 11:49 ? 00:00:00 [kworker/0:1]
1 S root 34762 2 0 80 0 - 0 worker 11:50 ? 00:00:00 [kworker/0:3]
4 S root 34824 1024 31 80 0 - 43170 poll_s 11:51 ? 00:00:00 sshd: anthony [priv]
5 S anthony 34829 34824 0 80 0 - 43170 poll_s 11:51 ? 00:00:00 sshd: anthony@notty
0 R anthony 34830 34829 0 80 0 - 40340 - 11:51 ? 00:00:00 ps -elf
Ich habe dieses Verhalten schon einmal erlebt, konnte aber keine bessere Referenz als diese AskUbuntu-Antwort finden .
Pkill-Verhalten
Da pkill -f asdf || true
es sich nicht um einen einfachen Befehl handelt (es handelt sich um eine Befehlsliste ), kann die oben genannte Optimierung nicht durchgeführt werden. Wenn Sie diesen Befehl ausführen ssh pi@10.20.0.10 "pkill -f asdf || true"
, wird er vom sshd
Prozess gegabelt und ausgeführt bash -c "pkill -f asdf || true"
.
Wie die Antwort von ctx zeigt, pkill
wird es seinen eigenen Prozess nicht beenden. Es wird jedoch jeder andere Prozess beendet, dessen Befehlszeile dem -f
Muster entspricht. Der bash -c
Befehl stimmt mit diesem Muster überein, sodass er diesen Prozess abbricht - seinen eigenen übergeordneten Prozess (wie es geschieht).
Der SSH-Server stellt dann fest, dass der Shell-Prozess, den er zum Ausführen der Remotebefehle gestartet hat, unerwartet beendet wurde, sodass ein Fehler an den SSH-Client gemeldet wird.
pkill
beim Beenden des übergeordneten Shell-Prozesses der Fall ist, weil die Argumentliste mit dem regulären Ausdruck übereinstimmt, werde ich einen terminologischen Einwand erheben: Esx || y
handelt sich nicht um einen zusammengesetzten Befehl , sondern um eine Befehlsliste .