Sua suposição de que é ela sshmesma que retorna o status de saída 255 está correta. A sshpágina do manual afirma que:
O ssh sai com o status de saída do comando remoto ou com 255 se ocorreu um erro.
Se você simplesmente executasse ssh pi@10.20.0.10 "pkill -f asdf", provavelmente obteria um status de saída 1correspondente ao pkillstatus de " Nenhum processo correspondido ".
A parte desafiadora é entender por que ocorre um erro no SSH quando você executa
ssh pi@10.20.0.10 "pkill -f asdf || true"
Comandos remotos SSH
O servidor SSH inicia um shell para executar comandos remotos. Aqui está um exemplo disso em ação:
$ 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
Observe que o shell padrão é bashe que o comando remoto não é um comando simples, mas um pipeline , “uma sequência de um ou mais comandos separados pelo operador de controle |”.
O shell Bash é inteligente o suficiente para perceber que, se o comando que está sendo passado pela -copção for um comando simples , ele pode otimizar não sendo realmente bifurcado em um novo processo, ou seja, é diretamente execo comando simples em vez de passar pela etapa extra de forking antes que ele execé. Aqui está um exemplo do que acontece quando você executa um comando simples remoto ( ps -elfneste caso):
$ 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
Já deparei com esse comportamento antes, mas não consegui encontrar uma referência melhor além desta resposta do AskUbuntu .
comportamento pkill
Como pkill -f asdf || truenão é um comando simples (é uma lista de comandos ), a otimização acima pode não ocorrer; portanto, quando você executa ssh pi@10.20.0.10 "pkill -f asdf || true", o sshdprocesso bifurca e executa bash -c "pkill -f asdf || true".
Como a resposta da ctx aponta, pkillnão matará seu próprio processo. No entanto, ele vai matar qualquer outro processo cuja linha de comando corresponde ao -fpadrão. O bash -ccomando corresponde a esse padrão e mata esse processo - seu próprio pai (por acaso).
O servidor SSH vê, então, que o processo do shell iniciado para executar os comandos remotos foi interrompido inesperadamente e, portanto, relata um erro ao cliente SSH.
pkillmata seu processo de shell pai porque sua lista arg corresponde ao regexp, levantarei uma objeção terminológica: nãox || yé um comando composto , é uma lista de comandos .