pkill возвращает 255 в сочетании с другой командой через удаленный ssh

Когда я пытаюсь выполнить pkill на удаленном хосте в сочетании с другой командой, он всегда возвращает 255, даже если обе команды были успешными.

Примеры

  1. ssh <remoteHost> 'pkill -f xyz' # returns 0 (rightly so when xyz is a process)
    
  2. ssh <remoteHost> 'source /etc/profile' # returns 0 (rightly so)
    

Но когда я запускаю комбинационную команду:

  1. ssh <remoteHost> 'source /etc/profile; pkill -f xyz' # returns 255 - why?
    

Есть что-то в "pkill" в сочетании с другой командой, потому что следующее возвращает ноль, даже если это комбинация:

  1. ssh <remoteHost> 'source /etc/profile; ls' # returns 0
    

Предположим, что xyz работает все время, когда мы пытаемся убить его.

Я не понимаю это поведение. Почему он возвращает 255 в случае 3?

1 ответ

Решение

Документация для Пкилл -f вариант говорит:

-f
Шаблон обычно сопоставляется только с именем процесса. Когда -f установлен, используется полная командная строка.

Так pkill -f xyz убьет любой процесс с "xyz" в любом месте его командной строки.

Когда ты бежишь ssh <remoteHost> 'source /etc/profile; pkill -f xyz', удаленный ssh-сервер будет запускать эквивалент этого от вашего имени:

$SHELL -c 'source /etc/profile; pkill -f xyz'

Результирующий экземпляр оболочки представляет собой процесс с "xyz" в командной строке. Я думаю, что pkill убивает его, а ssh сообщает о прекращенном сеансе как код выхода 255, например:

$ ssh localhost 'kill $$'
$ echo $?
255

Это не происходит, когда вы просто бежите ssh <remoteHost> 'pkill -f xyz'потому что некоторые оболочки вроде bash оптимизируют для этого случая. Вместо запуска pkill в качестве подпроцесса, экземпляр оболочки заменит себя процессом pkill. Таким образом, к моменту запуска pkill процесс оболочки с "xyz" в командной строке исчезает.

Вероятно, вы можете обойти это, запустив pkill следующим образом:

ssh <remoteHost> 'source /etc/profile; exec pkill -f xyz'

Если это не сработает, вы можете указать шаблон pkill таким образом, чтобы он не соответствовал самому шаблону. Например:

ssh <remoteHost> 'source /etc/profile; exec pkill -f "[x]yz"'

Шаблон [x]yz соответствует тексту "xyz", поэтому pkill убьет процессы, в которых появляется текст "xyz". Но шаблон не совпадает сам по себе, поэтому pkill не будет убивать процессы, где шаблон появляется.

Другие вопросы по тегам