GNU/Linux >> Znalost Linux >  >> Linux

Oring s True In A Command Over Ssh?

Když se pokusím spustit pkill -f vzdáleně přes ssh a pokusit se zahodit možný chybový kód (abych mohl pokračovat se zbytkem mého skriptu, i když nebyl nalezen žádný proces), || true se nechová tak, jak očekávám.

$ pkill asdf || true
$ echo $?
0
$ pkill -f asdf || true
$ echo $?
0
$ ssh [email protected] "pkill asdf || true"
$ echo $?
0
$ ssh [email protected] "pkill -f asdf || true"
255

Předpokládám, že je to ssh to vrátí 255, ne příkaz mezi uvozovkami, ale proč?

Přijatá odpověď:

Váš předpoklad, že je to ssh sám, který vrací 255 návratový stav, je správný. ssh manuálová stránka uvádí, že:

ssh se ukončí se stavem ukončení vzdáleného příkazu nebo s 255, pokud došlo k chybě.

Pokud byste jednoduše spustili ssh [email protected] "pkill -f asdf" , s největší pravděpodobností dostanete stav ukončení 1 , což odpovídá pkill stav pro „Neodpovídají žádné procesy “.

Náročnou částí je pochopit proč při spuštění dojde u SSH k chybě

ssh [email protected] "pkill -f asdf || true"

Vzdálené příkazy SSH

SSH server spustí shell pro spuštění vzdálených příkazů. Zde je příklad toho v akci:

$ 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: [email protected]
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

Všimněte si, že výchozí shell je bash a že vzdálený příkaz není jednoduchý příkaz, ale kanál, „sekvence jednoho nebo více příkazů oddělených řídicím operátorem | “.

Shell Bash je dostatečně chytrý na to, aby si uvědomil, že pokud je mu příkaz předán pomocí -c volba je jednoduchý příkaz, může se optimalizovat tím, že ve skutečnosti neforkuje nový proces, tj. přímo exec Je to jednoduchý příkaz namísto procházení dalším krokem fork ing před tím exec s. Zde je příklad toho, co se stane, když spustíte vzdálený jednoduchý příkaz (ps -elf v tomto případě):

$ 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: [email protected]
0 R anthony  34830 34829  0  80   0 - 40340 -      11:51 ?        00:00:00 ps -elf

S tímto chováním jsem se již setkal dříve, ale nemohl jsem najít lepší referenci než tuto odpověď AskUbuntu.

Související:Jaký je rozdíl mezi středníkem a dvojitým a&&?

pkill chování

Protože pkill -f asdf || true není jednoduchý příkaz (je to seznam příkazů), výše uvedená optimalizace nemůže nastat, takže když spustíte ssh [email protected] "pkill -f asdf || true" , sshd proces forks a execs bash -c "pkill -f asdf || true" .

Jak ukazuje odpověď ctx, pkill nezabije svůj vlastní proces. Nicméně bude zabít jakýkoli jiný proces, jehož příkazový řádek odpovídá -f vzor. bash -c příkaz odpovídá tomuto vzoru, takže zabije tento proces – jeho vlastního rodiče (jak se to stane).

SSH server pak vidí, že proces shellu, který spustil za účelem spouštění vzdálených příkazů, byl neočekávaně zabit, takže ohlásí chybu klientovi SSH.


Linux
  1. Příkaz sshpass:Neinteraktivní ověřování hesla pomocí SSH

  2. Odeslání hesla přes SSH nebo SCP pomocí subprocess.Popen

  3. SSH s autorizovanými klíči do systému Ubuntu se zašifrovaným homedir?

  1. Příkaz Nohup s příklady

  2. JQ Command v Linuxu s příklady

  3. Jak zabít příkazový řádek Chromium přes Ssh?

  1. Vynechejte váš linuxový firewall pomocí SSH přes HTTP

  2. Uživatelské jméno a heslo v příkazovém řádku s sshfs

  3. SSH - Jak zahrnout příkaz -t do souboru ~/.ssh/config