Ваше припущення, що саме він 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використовує просту команду замість того, щоб пройти додатковий крок з forkING до того , як 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це НЕ команда з'єднання , це список команд .