Ваше припущення, що саме він ssh
повертає статус виходу 255, є правильним. На ssh
сторінці чоловіка зазначено, що:
ssh виходить зі статусом виходу віддаленої команди або з 255, якщо сталася помилка.
Якби ви просто запустили ssh pi@10.20.0.10 "pkill -f asdf"
, ви, швидше за все, отримаєте статус виходу 1
, що відповідає pkill
статусу " Жоден процес не узгоджується ".
Найскладніша частина полягає в тому, щоб зрозуміти, чому виникає помилка при SSH при запуску
ssh pi@10.20.0.10 "pkill -f asdf || true"
Віддалені команди SSH
Сервер SSH запускає оболонку для запуску віддалених команд. Ось приклад цього в дії:
$ 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
Зауважте, що оболонка за замовчуванням є bash
і що віддалена команда - це не проста команда, а конвеєр , «послідовність однієї або декількох команд, розділених оператором керування |
».
Оболонка Bash є достатньо розумною, щоб зрозуміти, що якщо команда, яка передається їй за допомогою -c
параметра, є простою командою , вона може оптимізуватися, фактично не примушуючи новий процес, тобто вона безпосередньо exec
використовує просту команду замість того, щоб пройти додатковий крок з fork
ING до того , як exec
с. Ось приклад того, що відбувається під час запуску простої віддаленої команди ( ps -elf
у цьому випадку):
$ 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
Я раніше стикався з такою поведінкою, але не зміг знайти кращого посилання, окрім цієї відповіді AskUbuntu .
поведінка pkill
Так як pkill -f asdf || true
це не проста команда (це список команд ), вище оптимізації не можуть відбутися так , при запуску ssh pi@10.20.0.10 "pkill -f asdf || true"
, в sshd
процесі вилки і Execs bash -c "pkill -f asdf || true"
.
Як вказується у відповіді ctx, pkill
не вбиватиме власний процес. Тим НЕ менше, він буде вбивати будь-який інший процес , командний рядок якого відповідає -f
шаблоном. bash -c
Команда відповідає цим шаблоном , так що вбиває цей процес - його власний батько (як це відбувається).
Потім сервер SSH бачить, що процес оболонки, який він розпочався для запуску віддалених команд, був несподівано вбитий, тому він повідомляє про помилку клієнту SSH.
pkill
вбиває його процес оболонки батьківського , тому що його АГД список збігається з регулярним виразом, я підніму термінологічну заперечення:x || y
це НЕ команда з'єднання , це список команд .