Essere disconnesso da una sessione SSH uccide i tuoi programmi?


89

Quindi, dico mi disconnetto da uno SSH-sessione dopo ho iniziato rsynco cpo qualsiasi altro comando che può essere lungo in esecuzione. Quel comando continua a funzionare fino al termine dopo che mi disconnetto o viene ucciso?

Mi sono sempre chiesto questo.


Voglio solo aggiungere ciò che è stato detto sopra che, se ti trovi in ​​una situazione in cui devi mettere un processo già in esecuzione screen, prova reptyr .
un tizio triste il

Ucciderà i tuoi programmi. Molto fastidioso se stai aggiornando la versione del sistema operativo da dire Ubuntu 16.04 a 17.10 tramite SSH
kurdtpage

Risposte:


118

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=noin /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 pstreecomando.

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 SIGHUPi 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 nohupcomando 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. tmuxe screensono 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à HUPe 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.


3
Aggiungerei anche il comando 'dtach' a quell'elenco - è una specie di opposto di screen / tmux in quanto consente di collegare più terminali a una singola sessione ed è anche ottimo per prolungare una sessione, anche se non lo fa fornire qualsiasi mezzo per riprodurre la storia recente.
soffice

dtachurl è qui: dtach.sourceforge.net
slm

2
spiegazione eccellente. Mi sento già più linuxey!
fregas,

3
Inoltre, anche se tecnicamente non fa parte della tua risposta, ecco un curioso trivia: puoi usare kill -HUPcome root per forzare il terminale di qualcuno a riagganciare. Non dovresti farlo senza una buona ragione. Ottengo gran parte del mio chilometraggio quando gli utenti lasciano le shell in esecuzione durante la manutenzione e ho bisogno di smontare un filesystem che la loro shell mantiene aperta. Se l'utente è connesso ma terminale inattivo, invia il segnale al processo sshd. Altrimenti, se è in esecuzione all'interno di un multiplexer terminale, inviarlo alla shell che si desidera arrestare. Appendi solo il guscio per impedirti di lavorare!
Andrew B,

@AndrewB, potresti per favore approfondire come "il processo demone SSH ... decide che la tua connessione è interrotta"? E come posso sapere se il demone SSH pensa / sa che la (quale) connessione è morta o no?
Xiao Peng - ZenUML.com,

22

Come altri hanno già detto, una volta che ti disconnetti da ssh, tutto ciò che è in esecuzione scompare.

Come hanno menzionato @Michael Hampton e altri, è possibile utilizzare strumenti come tmuxo screenper disconnettere / riconnettersi ai terminali senza perdere il loro contenuto (ad esempio i processi figlio).

Inoltre, puoi mettere un processo in background usando una &e commerciale e quindi usare il comando disownper dissociarli con la 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
%

È possibile ricollegare una sessione terminale a un disownprocesso ed?
Nome falso

4
Sì. Vedi questa domanda U&L per i dettagli: unix.stackexchange.com/questions/4034/…
slm

13

No, tutti i programmi ancora collegati al terminale e non collocati in background con qualcosa del genere nohupverrebbero uccisi.

Questo è il motivo per cui esistono soluzioni terminali virtuali come tmuxquelle precedenti screenche creano sessioni che continuano a funzionare anche se si è disconnesse e alle quali è possibile ricollegarsi in un secondo momento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.