Twoje przypuszczenie, że to on ssh
sam zwraca kod wyjścia 255, jest prawidłowe. Thessh
Strona mężczyzna stwierdza, że:
ssh kończy pracę ze statusem wyjścia polecenia zdalnego lub z 255, jeśli wystąpił błąd.
Jeśli po prostu ssh pi@10.20.0.10 "pkill -f asdf"
chcesz uruchomić , najprawdopodobniej uzyskasz status wyjścia 1
odpowiadający pkill
statusowi „ Brak dopasowanych procesów ”.
Wyzwaniem jest zrozumienie, dlaczego podczas uruchamiania występuje błąd SSH
ssh pi@10.20.0.10 "pkill -f asdf || true"
Zdalne polecenia SSH
Serwer SSH uruchamia powłokę w celu uruchomienia zdalnych poleceń. Oto przykład tego w akcji:
$ 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
Zauważ, że domyślną powłoką jest bash
i że zdalne polecenie nie jest prostym poleceniem, lecz potokiem , „sekwencją jednego lub więcej poleceń oddzielonych przez operatora sterującego|
”.
Powłoka Bash jest na tyle sprytna, aby zdać sobie sprawę, że jeśli polecenie przekazane do niej przez -c
opcję jest prostym poleceniem , można je zoptymalizować, nie wykonując nowego procesu, tj. Bezpośrednio exec
jest to proste polecenie zamiast przejść przez dodatkowy krok z fork
ing zanim exec
s. Oto przykład tego, co dzieje się po uruchomieniu zdalnej prostej komendy ( ps -elf
w tym przypadku):
$ 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
Zetknąłem się z tym już wcześniej, ale nie mogłem znaleźć lepszego źródła niż ta odpowiedź AskUbuntu .
zachowanie pkill
Ponieważ pkill -f asdf || true
nie jest to proste polecenia (jest to lista poleceń ), powyższe optymalizacja nie może nastąpić po uruchomieniu tak ssh pi@10.20.0.10 "pkill -f asdf || true"
, te sshd
widły procesowych i execsbash -c "pkill -f asdf || true"
.
Jak wskazuje odpowiedź ctx, pkill
nie zabije własnego procesu. Jednak to będzie zabić jakiegokolwiek innego procesu, którego linia poleceń pasuje do -f
wzorca. bash -c
Komenda pasuje ten wzorzec tak zabija ten proces - własnego rodzica (jak to się dzieje).
Serwer SSH następnie widzi, że proces powłoki, który uruchomił w celu uruchomienia poleceń zdalnych, został nieoczekiwanie zabity, więc zgłasza błąd klientowi SSH.
pkill
zabijającego proces powłoki nadrzędnej, ponieważ jego lista argumentów jest zgodna z wyrażeniem regularnym, podniosę zastrzeżenie terminologiczne:x || y
to nie jest złożone polecenie , to lista poleceń .