Su suposición de que es en ssh
sí misma la que devuelve el estado de salida 255 es correcta. La ssh
página del manual dice que:
ssh sale con el estado de salida del comando remoto o con 255 si se produjo un error.
Si simplemente ejecutara ssh pi@10.20.0.10 "pkill -f asdf"
, lo más probable es que obtenga un estado de salida de 1
, correspondiente al pkill
estado de " No hay procesos coincidentes ".
La parte difícil es entender por qué ocurre un error con SSH cuando ejecuta
ssh pi@10.20.0.10 "pkill -f asdf || true"
Comandos remotos SSH
El servidor SSH lanza un shell para ejecutar comandos remotos. Aquí hay un ejemplo de esto en acción:
$ 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
Tenga en cuenta que el shell predeterminado es bash
y que el comando remoto no es un comando simple sino una tubería , "una secuencia de uno o más comandos separados por el operador de control |
".
El shell Bash es lo suficientemente inteligente como para darse cuenta de que si el comando que le pasa la -c
opción es un comando simple , puede optimizar al no bifurcar un nuevo proceso, es decir, es directamente exec
el comando simple en lugar de pasar por el paso adicional de fork
ing antes de exec
s. Aquí hay un ejemplo de lo que sucede cuando ejecuta un comando simple remoto ( ps -elf
en este 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
Me he encontrado con este comportamiento antes, pero no pude encontrar una referencia mejor que esta respuesta de AskUbuntu .
comportamiento de pkill
Como pkill -f asdf || true
no es un comando simple (es una lista de comandos ), la optimización anterior no puede ocurrir, por lo tanto, cuando ejecuta ssh pi@10.20.0.10 "pkill -f asdf || true"
, el sshd
proceso se bifurca y ejecuta bash -c "pkill -f asdf || true"
.
Como señala la respuesta de ctx, pkill
no matará su propio proceso. Sin embargo, será matar a cualquier otro proceso cuya línea de comandos coincide con el -f
patrón. El bash -c
comando coincide con este patrón, por lo que mata este proceso, su propio padre (como sucede).
El servidor SSH luego ve que el proceso de shell que inició para ejecutar los comandos remotos se cerró inesperadamente, por lo que informa un error al cliente SSH.
pkill
mata su proceso de shell principal porque su lista de argumentos coincide con la expresión regular, plantearé una objeción de terminología: nox || y
es un comando compuesto , es una lista de comandos .