Právě jsem si všiml, že když spustím ssh [email protected]_host tail -f /some/file a poté tail -f /some/file běží na vzdáleném hostiteli, i když je připojení ssh uzavřeno!
Takže po několika připojeních a odpojeních počet spuštěných tail -f /some/file roste. Jak vlastně ukončit tail -f když je připojení ssh uzavřeno?
Přijatá odpověď:
V
ssh host tail -f file
ssh klient se připojí k sshd server na host přes TCP spojení. sshd spustí tail -f s jeho stdout přesměrovaným do potrubí. sshd přečte, co přichází z druhého konce roury, a zapouzdří to do protokolu sshd, aby je poslal do ssh klienta. (pomocí rshd , tail stdout by byl přímo soket, ale sshd přidává šifrování a je schopen multiplexovat několik streamů (jako pro port/agent/X11/přesměrování tunelu, stderr) na jediné TCP spojení, takže se musí uchýlit k rourám).
Když stisknete CTRL-C, do ssh se odešle SIGINT klienta. To způsobí ssh zemřít. Po smrti je TCP spojení uzavřeno. A proto na host , sshd umírá také. tail není zabit, ale jeho stdout je nyní roura bez čtečky na druhém konci. Takže až příště něco napíše do svého stdoutu, dostane SIGPIPE a zemře.
V:
ssh -t host 'tail -f file'
Je to to samé, až na to, že místo toho, aby se jednalo o rouru, komunikace mezi sshd a tail je přes pseudoterminál. tail ‘s stdout je podřízený pseudoterminál (jako /dev/pts/12 ) a jakýkoli tail zápis tam je read na hlavní straně (pravděpodobně upraveno disciplínou tty line) pomocí sshd a odeslány zapouzdřené do ssh klient.
Na straně klienta pomocí -t , ssh přepne terminál do raw režimu. Konkrétně to deaktivuje kanonický režim terminálu a zpracování terminálového signálu.
Když tedy stisknete Ctrl+C namísto toho, aby disciplína terminálové linky klienta odeslala SIGINT do ssh úloha, která pouze odešle ^C znak přes připojení k sshd a sshd zapíše, že ^C na hlavní stranu vzdáleného terminálu. A linková disciplína vzdáleného terminálu odešle SIGINT na tail . tail pak zemře a sshd ukončí a uzavře připojení a ssh se ukončí (pokud není jinak stále zaneprázdněn přesměrováním portů nebo jiným).
Také pomocí -t , pokud ssh klient zemře (například pokud zadáte ~. ), spojení je uzavřeno a sshd zemře. V důsledku toho bude SIGHUP odeslán na tail .
Nyní pozor, pomocí -t má vedlejší účinky. Například s výchozím nastavením terminálu \n znaky jsou převedeny na \r\n a v závislosti na vzdáleném systému se může stát více věcí, takže možná budete chtít vydat stty -opost (pro zakázání následného zpracování výstupu) na vzdáleném hostiteli, pokud tento výstup není určen pro terminál:
$ ssh localhost 'echo x' | hd
00000000 78 0a |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000 78 0d 0a |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000 78 0a |x.|
00000002
Další nevýhodou použití -t /-tt je, že stdout a stderr nejsou na klientovi rozlišeny. Jak stdout, tak stderr vzdáleného příkazu budou zapsány do ssh stdout klienta:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1