Nel
ssh host tail -f file
Il ssh
client si connette al sshd
server su host
una connessione TCP. sshd
viene eseguito 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 da inviare al ssh
client. (con rshd
, tail
stdout sarebbe stato il socket direttamente, ma sshd
aggiunge la crittografia ed è in grado di multiplexare diversi flussi (come per il reindirizzamento port / agent / X11 / tunnel, stderr) su una singola connessione TCP, quindi deve ricorrere alle pipe).
Quando si preme CTRL-C, un SIGINT viene inviato al ssh
client. Questo fa ssh
morire. Alla morte la connessione TCP viene chiusa. E quindi, anche host
, sshd
muore. tail
non viene ucciso, ma il suo stdout è ora una pipe senza lettore dall'altra parte. Quindi, la prossima volta che scrive qualcosa sul suo stdout, riceverà un SIGPIPE e morirà.
Nel:
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
Lo stdout è uno pseudo-terminale slave (come /dev/pts/12
) e qualunque cosa tail
scriva read
sul lato master (possibilmente modificato dalla disciplina tty line) da sshd
e inviato incapsulato al ssh
client.
Sul lato client, con -t
, ssh
mette il terminale in raw
modalità. In particolare, ciò disabilita la modalità canonica terminale e la gestione del segnale terminale.
Quindi, quando si preme Ctrl+C, invece della disciplina della linea terminale del client che invia un SIGINT al ssh
lavoro, che invia semplicemente il ^C
carattere sulla connessione sshd
e lo sshd
scrive ^C
sul lato principale del terminale remoto. E la disciplina di linea del terminale remoto invia un SIGINT
a tail
. tail
quindi muore, sshd
esce e chiude la connessione e ssh
termina (se non è comunque occupato con il port forwarding o altro).
Inoltre, con -t
, se il ssh
client muore (ad esempio se si immette ~.
), la connessione viene chiusa e sshd
muore. Di conseguenza, verrà inviato un SIGHUP tail
.
Ora, attenzione che l'utilizzo -t
ha effetti collaterali. Ad esempio, con le impostazioni predefinite del terminale, i \n
caratteri vengono convertiti in \r\n
e potrebbero accadere altre cose a seconda del sistema remoto, quindi potresti voler emettere un stty -opost
(per disabilitare la post-elaborazione dell'output) sull'host remoto se quell'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'uso di -t
/ -tt
è che stdout e stderr non sono differenziati sul client. Sia lo stdout che lo stderr del comando remoto verranno scritti nello ssh
stdout del client:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1