Votre supposition que c'est ssh
lui - même qui renvoie le statut de sortie 255 est correcte. La ssh
page de manuel indique que:
ssh se ferme avec l'état de sortie de la commande à distance ou avec 255 en cas d'erreur.
Si vous deviez simplement exécuter ssh pi@10.20.0.10 "pkill -f asdf"
, vous obtiendriez très probablement un statut de sortie de 1
, correspondant au pkill
statut « Aucun processus correspondant ».
La partie difficile est de comprendre pourquoi une erreur se produit avec SSH lorsque vous exécutez
ssh pi@10.20.0.10 "pkill -f asdf || true"
Commandes à distance SSH
Le serveur SSH lance un shell pour exécuter des commandes à distance. Voici un exemple de ceci en action:
$ 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
Notez que le shell par défaut est bash
et que la commande distante n'est pas une simple commande mais un pipeline , "une séquence d'une ou plusieurs commandes séparées par l'opérateur de contrôle |
".
Le shell Bash est suffisamment intelligent pour se rendre compte que si la commande qui lui est passée par l' -c
option est une commande simple , il peut optimiser en ne forçant pas réellement un nouveau processus, c'est-à-dire qu'il est directement exec
la commande simple au lieu de passer par l'étape supplémentaire d’ fork
ing avant lui exec
. Voici un exemple de ce qui se passe lorsque vous exécutez une commande simple à distance ( ps -elf
dans ce cas):
$ 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'ai rencontré ce comportement auparavant, mais je n'ai pas pu trouver une meilleure référence autre que cette réponse AskUbuntu .
comportement pkill
Étant donné qu'il pkill -f asdf || true
ne s'agit pas d'une simple commande (c'est une liste de commandes ), l'optimisation ci-dessus ne peut pas se produire, donc lorsque vous exécutez ssh pi@10.20.0.10 "pkill -f asdf || true"
, le sshd
processus se déroule et s'exécute bash -c "pkill -f asdf || true"
.
Comme le souligne la réponse de ctx, pkill
ne tuera pas son propre processus. Cependant, il va tuer tout autre processus dont la ligne de commande correspond à la -f
configuration. La bash -c
commande correspond à ce modèle, donc elle tue ce processus - son propre parent (en l'occurrence).
Le serveur SSH voit alors que le processus shell qu'il a démarré pour exécuter les commandes à distance a été tué de manière inattendue, il signale donc une erreur au client SSH.
pkill
tue son processus shell parent car sa liste d'arguments correspond à l'expression rationnelle, je soulèverai une objection de terminologie: cex || y
n'est pas une commande composée , c'est une liste de commandes .