Soluzione 1:
Modifica per il 2016:
Questa domanda e risposta precede la debacle di systemd v230. A partire da systemd v230, la nuova impostazione predefinita consiste nell'uccidere tutti i figli di una sessione di accesso terminata, indipendentemente dalle precauzioni storicamente valide prese per impedirlo. Il comportamento può essere modificato impostando KillUserProcesses=no
in /etc/systemd/logind.conf
, o aggirato utilizzando i meccanismi specifici di systemd per l'avvio di un demone nello spazio utente. Questi meccanismi esulano dallo scopo di questa domanda.
Il testo seguente descrive come le cose hanno tradizionalmente funzionato nello spazio di progettazione UNIX da più tempo rispetto a Linux.
Verranno uccisi, ma non necessariamente immediatamente. Dipende da quanto tempo impiega il demone SSH a decidere che la tua connessione è morta. Quella che segue è una spiegazione più lunga che ti aiuterà a capire come funziona effettivamente.
Quando hai effettuato l'accesso, il demone SSH ha assegnato uno pseudo-terminale per te e lo ha collegato alla shell di accesso configurata dell'utente. Questo è chiamato il terminale di controllo. Ogni programma che avvii normalmente a quel punto, non importa quanti strati di shell siano profondi, alla fine farà risalire i suoi antenati a quella shell. Puoi osservarlo con il pstree
comando.
Quando il processo del demone SSH associato alla tua connessione decide che la tua connessione è interrotta, invia un segnale di riaggancio (SIGHUP
) alla shell di login. Questo notifica al guscio che sei scomparso e che dovrebbe iniziare a ripulirsi da solo. Ciò che accade a questo punto è specifico della shell (cerca "HUP" nella sua pagina di documentazione), ma per la maggior parte inizierà a inviare SIGHUP
all'esecuzione dei lavori ad esso associati prima di terminare. Ciascuno di questi processi, a sua volta, farà tutto ciò per cui è configurato al ricevimento di quel segnale. Di solito questo significa terminare. Se quei lavori hanno lavori propri, anche il segnale verrà spesso trasmesso.
I processi che sopravvivono a un blocco del terminale di controllo sono quelli che si sono dissociati dall'avere un terminale (processi demone che hai avviato al suo interno) o quelli che sono stati invocati con un prefisso nohup
comando. (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 da parte dell'amministratore per ricaricare la configurazione. Ironia della sorte, ciò significa che la maggior parte degli amministratori non apprende l'uso di "riaggancio" di questo segnale per i non demoni fino a molto, molto più tardi. Ecco perché stai leggendo questo!
I multiplexer di terminale sono un modo comune per mantenere intatto l'ambiente della shell tra le disconnessioni. Ti consentono di staccarti dai processi della tua shell in modo da poterli ricollegare in seguito, indipendentemente dal fatto che tale 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 tua connessione è interrotta. Questo è un comportamento specifico per ogni implementazione di un demone SSH, ma puoi contare su tutti per terminare quando entrambe le parti reimpostano la connessione TCP. Ciò avverrà rapidamente se il server tenta di scrivere sul socket e i pacchetti TCP non vengono riconosciuti, o lentamente se nulla sta tentando di scrivere sul PTY.
In questo particolare contesto, i fattori che più probabilmente innescano una scrittura sono:
- Un processo (tipicamente quello in primo piano) che tenta di scrivere sul PTY lato server. (server->client)
- L'utente che sta tentando di scrivere sul PTY lato client. (client->server)
- Keepalive di qualsiasi tipo. Questi di solito non sono abilitati per impostazione predefinita, né dal client né dal server, e in genere ci sono due tipi:a livello di applicazione e basati su TCP (ad esempio
SO_KEEPALIVE
). I keepalive equivalgono al server o al client che invia raramente pacchetti dall'altra parte, anche quando nulla avrebbe altrimenti motivo di scrivere sul socket. Anche se in genere questo ha lo scopo di aggirare i firewall che interrompono le connessioni troppo rapidamente, ha l'effetto collaterale aggiuntivo di far notare al mittente quando l'altra parte non risponde molto più rapidamente.
In questo caso si applicano le solite regole per le sessioni TCP:se c'è un'interruzione nella connettività tra il client e il server, ma nessuna delle parti tenta di inviare un pacchetto durante il problema, la connessione sopravviverà a condizione che entrambe le parti rispondano in seguito e ricevano il TCP previsto numeri di sequenza.
Se una parte ha deciso che il socket è morto, gli effetti sono tipicamente immediati:il processo sshd invierà HUP
e terminare automaticamente (come descritto in precedenza), oppure il client avviserà l'utente del problema rilevato. Vale la pena notare che solo perché una parte pensa che l'altra sia morta non significa che l'altra ne sia stata informata. Il lato orfano della connessione rimarrà in genere aperto fino a quando non tenterà di scrivere su di esso e scadrà o riceverà un ripristino TCP dall'altro lato. (se la connettività era disponibile in quel momento) La pulizia descritta in questa risposta avviene solo una volta che il server ha notato.
Soluzione 2:
Come altri hanno già detto, una volta disconnesso da ssh, tutto ciò che è in esecuzione al suo interno non c'è più.
Come hanno menzionato @Michael Hampton e altri, puoi usare strumenti come tmux
o screen
per disconnettersi/riconnettersi ai terminali senza perdere il loro contenuto (cioè i processi figlio).
Inoltre puoi mettere un processo in secondo piano usando una e commerciale &
e poi usa il comando disown
per dissociarli dalla shell corrente.
# start a command
% sleep 5000 &
[1] 3820
# check it
% jobs
[1]+ Running sleep 5000 &
# disown everything
% disown -a
# check it again (gone from shell)
% jobs
%
# but it's still running on the system
% ps -eaf|grep "[s]leep"
saml 3820 23791 0 00:16 pts/1 00:00:00 sleep 5000
%
Soluzione 3:
No, tutti i programmi sono ancora collegati al terminale e non messi in background con qualcosa come nohup
, sarebbe stato ucciso.
Questo è il motivo per cui esistono soluzioni di terminali virtuali come tmux
e il vecchio screen
che creano sessioni che continuano a funzionare anche se sei disconnesso e alle quali puoi ricollegarti in seguito.