Modifica per il 2016:
Questo Q&A precede la debacle di systemd v230 . A partire da systemd v230, la nuova impostazione predefinita è l'eliminazione di tutti i figli di una sessione di accesso terminata, indipendentemente da quali precauzioni storicamente valide sono state prese per impedirlo. Il comportamento può essere modificato impostando KillUserProcesses=no
in /etc/systemd/logind.conf
, o aggirato utilizzando i meccanismi specifici systemd per iniziare un demone nello spazio utente. Tali meccanismi esulano dall'ambito di questa domanda.
Il testo seguente descrive il modo in cui le cose hanno funzionato tradizionalmente nello spazio di progettazione UNIX per un periodo più lungo di quanto esistesse Linux.
Verranno uccisi, ma non necessariamente immediatamente. Dipende da quanto tempo impiega il demone SSH a decidere che la connessione è interrotta. Quella che segue è una spiegazione più lunga che ti aiuterà a capire come funziona effettivamente.
Una volta effettuato l'accesso, il daemon SSH ha allocato uno pseudo-terminale per l'utente e lo ha collegato alla shell di accesso configurata dell'utente. Questo è chiamato terminale di controllo. Ogni programma che avvierai normalmente a quel punto, non importa quanti strati di shell siano profondi, alla fine rintracceranno i suoi antenati su quella shell. Puoi osservarlo con il pstree
comando.
Quando il processo daemon SSH associato alla connessione decide che la connessione è interrotta, invia un segnale di blocco ( SIGHUP
) alla shell di accesso. Questo avvisa il guscio che sei svanito e che dovrebbe iniziare a ripulire dopo se stesso. Ciò che accade a questo punto è specifico della shell (cerca "HUP" nella sua documentazione), ma per la maggior parte inizierà a inviare SIGHUP
i lavori in esecuzione associati prima di terminare. Ciascuno di questi processi, a sua volta, farà tutto ciò che è configurato per fare alla ricezione di quel segnale. Di solito questo significa terminare. Se quei lavori hanno lavori propri, anche il segnale viene spesso trasmesso.
I processi che sopravvivono a un blocco del terminale di controllo sono quelli che si sono dissociati dall'avere un terminale (processi daemon avviati al suo interno) o che sono stati invocati con un nohup
comando con prefisso . (cioè "non riattaccare su questo") I demoni interpretano il segnale HUP in modo diverso; poiché non dispongono di un terminale di controllo e non ricevono automaticamente un segnale HUP, viene invece riproposto come richiesta manuale dall'amministratore per ricaricare la configurazione. Ironia della sorte, ciò significa che la maggior parte degli amministratori non impara l'uso del "blocco" di questo segnale per i non demoni fino a molto, molto più tardi. Ecco perché stai leggendo questo!
I multiplexer terminali sono un modo comune per mantenere intatto l'ambiente shell tra le disconnessioni. Consentono di staccarsi dai processi della shell in modo da poterli ricollegare in un secondo momento, indipendentemente dal fatto che la disconnessione sia stata accidentale o intenzionale. tmux
e screen
sono i più popolari; la sintassi per usarli va oltre lo scopo della tua domanda, ma vale la pena esaminarli.
Mi è stato chiesto di elaborare quanto tempo impiega il demone SSH a decidere che la connessione è interrotta. Questo è un comportamento specifico per ogni implementazione di un demone SSH, ma puoi contare su tutti per terminare quando una delle parti ripristina la connessione TCP. Ciò accadrà rapidamente se il server tenta di scrivere sul socket e i pacchetti TCP non vengono riconosciuti o lentamente se nulla tenta di scrivere sul PTY.
In questo particolare contesto, i fattori che hanno più probabilità di innescare una scrittura sono:
- Un processo (in genere quello in primo piano) che tenta di scrivere sul PTY sul lato server. (Server-> client)
- L'utente sta tentando di scrivere sul PTY sul lato client. (Client-> server)
- Keepalives di qualsiasi tipo. Questi di solito non sono abilitati per impostazione predefinita, né dal client né dal server, e in genere ci sono due versioni: livello dell'applicazione e basato su TCP (cioè
SO_KEEPALIVE
). Keepalives equivale al server o al client che inviano raramente pacchetti dall'altra parte, anche se nulla avrebbe altrimenti un motivo per scrivere sul socket. Sebbene ciò abbia generalmente lo scopo di evitare ai firewall di timeout delle connessioni troppo rapidamente, ha l'effetto collaterale aggiunto di far notare al mittente quando l'altra parte non risponde molto più rapidamente.
Qui si applicano le solite regole per le sessioni TCP: se si verifica un'interruzione della connettività tra client e server, ma nessuna delle parti tenta di inviare un pacchetto durante il problema, la connessione sopravviverà a condizione che entrambe le parti rispondano successivamente e ricevano il TCP previsto numeri di sequenza.
Se una parte ha deciso che il socket è morto, gli effetti sono in genere immediati: il processo sshd invierà HUP
e terminerà automaticamente (come descritto in precedenza), oppure il client notificherà all'utente il problema rilevato. Vale la pena notare che solo perché una parte pensa che l'altra sia morta non significa che l'altra sia stata informata di ciò. Il lato orfano della connessione rimarrà generalmente aperto fino a quando non tenta di scrivere su di esso e scade o non riceve un ripristino TCP dall'altro lato. (se la connettività era disponibile al momento) La pulizia descritta in questa risposta avviene solo dopo che il server ha notato.
screen
, prova reptyr .