I programmi eseguiti da una sessione ssh dipendono dalla connessione?


29

Un programma eseguito da una sessione ssh dipende dalla connessione al client? Ad esempio quando la connessione è molto lenta. Quindi aspetta attivamente che le cose vengano stampate sullo schermo?

E se dipende dalla connessione, ad esempio succede anche con schermo o byobu ? Dal momento che con questi i programmi vengono mantenuti in esecuzione anche dopo la disconnessione dall'host.


Nota: ho trovato solo queste domande correlate:


1
Se la connessione viene persa, il programma continuerà a funzionare fino al timeout della sessione (a meno che non sia bloccato in un'operazione di stampa), ma se la sessione termina, il programma verrà terminato correttamente.
Sebb,

Risposte:


26

L'output dei programmi è bufferizzato, quindi se la connessione è lenta il programma verrà interrotto se il buffer si riempie.

Se lo usi screen, ha anche un buffer che usa per provare e visualizzare in una sessione connessa. Tuttavia, un programma collegato nella sessione dello schermo non verrà arrestato se screennon è possibile aggiornare il terminale remoto abbastanza velocemente. Proprio come quando si perde una connessione, il programma continua a riempire il screensbuffer fino a quando non trabocca (estraendo le informazioni più vecchie). Ciò che vedi arrivare (e può scorrere fino a) dipende da ciò che è (ancora) in quel buffer. screensepara efficacemente il tuo programma dal tuo terminale (e dalla tua lenta connessione SSH).


9

Una connessione SSH può morire prematuramente se la connessione TCP sottostante riceve un pacchetto con il flag RST . Ciò potrebbe accadere se una parte invia un pacchetto (che potrebbe essere una sonda keepalive SSH periodica) ma non riceve un riconoscimento TCP in un ragionevole lasso di tempo, o se un router decide che la connessione è stata inattiva troppo a lungo, o se un ISP è solo essere malvagio.

Nel modello di terminale Unix, quando la connessione del terminale viene interrotta, il driver del terminale invia un segnale HUP alla shell, la cui terminazione provoca anche l'invio di un SIGHUP ai processi in esecuzione nella shell.

Dalle FAQ del programmatore Unix , voce 1.15:

SIGHUPè un segnale che significa, per convenzione, "la linea terminale è stata bloccata". Non ha nulla a che fare con i processi padre e di solito viene generato dal driver tty (e consegnato al gruppo di processi in primo piano).

Tuttavia, come parte del sistema di gestione della sessione, ci sono esattamente due casi in cui SIGHUPviene inviato al termine di un processo:

  • Quando il processo che muore è il leader della sessione di una sessione collegata a un dispositivo terminale, SIGHUPviene inviato a tutti i processi nel gruppo di processi in primo piano di quel dispositivo terminale.

  • Quando la morte di un processo causa un gruppo processo scollegato, e uno o più processi nel gruppo orfano sono fermato , quindi SIGHUPe SIGCONTvengono inviati a tutti i membri del gruppo orfani. (Un gruppo di processi orfani è uno in cui nessun processo nel gruppo ha un genitore che fa parte della stessa sessione, ma non lo stesso gruppo di processi.)

Il gestore del segnale predefinito per SIGHUP è di terminare il processo:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process

Tuttavia, è possibile evitare la conclusione del processo.

  • È possibile inserire un gestore di segnale che ignora SIGHUP. Per farlo come utente, avvolgi il comando nohup. Per esempio:

    nohup make all &
    
  • Puoi dire alla shell di dissociare un processo figlio da esso. Ad esempio, Bash ha un disowncomando integrato:

    make all
    

    CtrlZ

    bg
    disown %1
    

    Quindi, SIGHUP non verrà propagato al bambino (che non è più un bambino).

  • Alcuni programmi, in particolare i demoni , useranno automaticamente i meccanismi sopra descritti: un programma può installare un gestore SIGHUP alternativo (usando sigaction(2)) o potrebbe scegliere di unirsi a una nuova sessione ( setsid(2)).
  • È possibile eseguire screeno tmux, che alloca uno pseudo-TTY per eseguire una sessione con una shell che non riceve SIGHUP quando la connessione SSH si interrompe. SIGHUP non viene inoltrato dalla sessione SSH alla sessione schermo / tmux.

Per inciso, un modo alternativo per gestire connessioni SSH inaffidabili è utilizzare invece il protocollo Mosh . Mosh funziona su UDP, quindi non esiste una connessione TCP che rischia di essere ripristinata.



1

Sì, un programma in esecuzione su SSH dipenderà dalla sua uscita andando da qualche parte. Se la connessione è lenta, l'output deve essere bufferizzato da qualche parte e i buffer non possono essere infiniti, quindi il programma deve bloccare se sono riempiti.

Nota che l'output potrebbe non andare necessariamente a un terminale: considera di eseguire qualcosa di simile

ssh user@somewhere "cat file.txt" > file.txt

Questo in effetti copierà il file. Perché ciò funzioni, la velocità di output di cat deve corrispondere a quella della connessione: dovrebbe essere ovvio che perdere parti dell'output dal centro sarebbe inaccettabile.

Lo schermo cambierà la situazione in quanto si comporta come un terminale e salverà ciò che dovrebbe essere mostrato "nella finestra del terminale" (più scrollback). Non ha bisogno di ricordare tutto ciò che il programma emette, solo le parti che si adattano alla "finestra" e allo scrollback. Per impostazione predefinita, lo schermo attenderà una connessione lenta (bloccando il programma), ma può essere configurato per rilevare una connessione bloccata impostando "non-block on".

Dalla pagina man:

nonblock [on | off | numsecs]

Spiega allo schermo come gestire le interfacce utente (display) che cessano di accettare l'output. Ciò può accadere se un utente preme ^ S o viene interrotta una connessione TCP / modem ma non viene ricevuto alcun blocco. Se il blocco non è disattivato (questa è l'impostazione predefinita) attende che il display si riavvii per accettare l'output. Se il blocco non è attivo, lo schermo attende fino al raggiungimento del timeout (acceso viene trattato come 1 secondo). Se il display continua a non ricevere caratteri, lo schermo lo considererà "bloccato" e interromperà l'invio di caratteri. Se a un certo punto si riavvia per accettare i caratteri, lo schermo sbloccherà il display e visualizzerà nuovamente il contenuto della finestra aggiornata.

Una disconnessione è diversa da una connessione lenta. Il semplice SSH non può ripristinarsi automaticamente da esso, quindi il tuo programma riceverà un SIGHUP. D'altra parte, lo schermo rileverà una disconnessione, si staccherà e tornerà al buffering locale fino a quando lo schermo non viene ricollegato. Ciò non bloccherà il programma in esecuzione.

(L'impostazione nonblock 1in your .screenrcè importante se si esegue qualcosa come irssi che produrrà continuamente output ma che dovrà comunque comunicare con la rete allo stesso tempo. Il blocco porterebbe a disconnettersi dall'IRC, il che è estremamente fastidioso ...)

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.