Ho appena notato che se eseguo ssh [email protected]_host tail -f /some/file , quindi tail -f /some/file continua a funzionare su remote_host anche se la connessione ssh è chiusa!
 Quindi, dopo diverse connessioni e disconnessioni, numero di tail -f /some/file in esecuzione cresce. Come terminare effettivamente tail -f quando la connessione ssh è chiusa?
Risposta accettata:
In
ssh host tail -f file
 Il ssh il client si connette a sshd server su host su una connessione TCP. sshd esegue tail -f con il suo stdout reindirizzato a una pipe. sshd legge ciò che proviene dall'altra estremità della pipe e lo incapsula nel protocollo sshd per inviarlo a ssh cliente. (con rshd , tail stdout sarebbe stato direttamente il socket, ma sshd aggiunge la crittografia ed è in grado di multiplexare diversi flussi (come per port/agent/X11/tunnel redirection, stderr) su una singola connessione TCP, quindi deve ricorrere alle pipe).
 Quando premi CTRL-C, viene inviato un SIGINT a ssh cliente. Ciò causa ssh morire. Alla morte, la connessione TCP viene chiusa. E quindi, su host , sshd muore anche lui. tail non viene ucciso, ma il suo stdout ora è una pipe senza lettore all'altra estremità. Quindi, la prossima volta che scrive qualcosa nel suo stdout, riceverà un SIGPIPE e morirà.
In:
ssh -t host 'tail -f file'
 È la stessa cosa tranne che invece di essere con una pipe, la comunicazione tra sshd e tail avviene tramite uno pseudo-terminale. tail 's stdout è uno pseudo-terminale slave (come /dev/pts/12 ) e qualunque tail scrivi c'è read sul lato master (possibilmente modificato dalla disciplina della linea tty) da sshd e inviato incapsulato a ssh cliente.
 Sul lato client, con -t , ssh mette il terminale in raw modalità. In particolare, ciò disabilita la modalità canonica del terminale e la gestione del segnale del terminale.
 Quindi, quando premi Ctrl+C , invece della disciplina della linea terminale del client che invia un SIGINT a ssh job, che invia semplicemente il ^C carattere sulla connessione a sshd e sshd scrive quel ^C al lato master del terminale remoto. E la disciplina di linea del terminale remoto invia un SIGINT a tail . tail poi muore e sshd esce e chiude la connessione e ssh termina (se non è altrimenti ancora occupato con port forwarding o altro).
 Inoltre, con -t , se ssh il cliente muore (ad esempio se inserisci ~. ), la connessione è chiusa e sshd muore. Di conseguenza, un SIGHUP verrà inviato a tail .
 Ora, fai attenzione che usando -t ha effetti collaterali. Ad esempio, con le impostazioni predefinite del terminale, \n i caratteri vengono convertiti in \r\n e più cose possono accadere a seconda del sistema remoto, quindi potresti voler emettere un stty -opost (per disabilitare la post-elaborazione dell'output) sull'host remoto se tale output non è destinato a un terminale:
$ 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
 Un altro svantaggio dell'utilizzo di -t /-tt è che stdout e stderr non sono differenziati sul client. Sia lo stdout che lo stderr del comando remoto verranno scritti in ssh stdout del cliente:
$ ssh localhost ls /x  | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1