GNU/Linux >> Linux Esercitazione >  >> Linux

Cosa determina esattamente se un lavoro in background viene interrotto quando la shell viene chiusa o terminata?

Un processo non viene "ucciso con SIGHUP" - almeno, non nel senso stretto del termine. Piuttosto, quando la connessione viene interrotta, al processo di controllo del terminale (in questo caso, Bash) viene inviato un segnale di riaggancio*, comunemente abbreviato in "segnale HUP", o semplicemente SIGHUP.

Ora, quando un processo riceve un segnale, può gestirlo come vuole**. L'impostazione predefinita per la maggior parte dei segnali (incluso HUP) è uscire immediatamente. Tuttavia, il programma è libero di ignorare invece il segnale, o anche di eseguire qualche tipo di funzione di gestione del segnale.

Bash sceglie l'ultima opzione. Il suo gestore di segnali HUP verifica se l'opzione "huponexit" è vera e, in tal caso, invia SIGHUP a ciascuno dei suoi processi figli. Solo una volta che ha finito, Bash esce.

Allo stesso modo, ogni processo figlio è libero di fare quello che vuole quando riceve il segnale:lascialo impostato sul valore predefinito (cioè muori immediatamente), ignoralo o esegui un gestore di segnale.

Nohup cambia solo l'azione predefinita per il processo figlio in "ignora". Una volta che il processo figlio è in esecuzione, tuttavia, è libero di modificare la propria risposta al segnale.

Questo, penso, è il motivo per cui alcuni programmi muoiono anche se li hai eseguiti con nohup:

  1. Nohup imposta l'azione predefinita su "ignora".
  2. Il programma deve eseguire una sorta di pulizia quando esce, quindi installa un gestore SIGHUP, sovrascrivendo accidentalmente il flag "ignora".
  3. Quando arriva il SIGHUP, il gestore viene eseguito, ripulendo i file di dati del programma (o qualsiasi altra cosa necessaria) ed esce dal programma.
  4. L'utente non conosce o non si preoccupa del gestore o della pulizia e vede solo che il programma è terminato nonostante nohup.

È qui che entra in gioco "rinnegare". Un processo che è stato rinnegato da Bash non riceve mai il segnale HUP, indipendentemente dall'opzione huponexit. Quindi, anche se il programma imposta il proprio gestore di segnale, il segnale non viene mai effettivamente inviato, quindi il gestore non viene mai eseguito. Tieni presente, tuttavia, che se il programma tenta di visualizzare del testo a un utente che è disconnesso, causerà un errore di I/O, che potrebbe causare comunque la chiusura del programma.

* E, sì, prima che tu lo chieda, la terminologia di "riagganciamento" è rimasta dai giorni dei mainframe dialup di UNIX.

** La maggior parte dei segnali, comunque. SIGKILL, ad esempio, sempre fa terminare immediatamente il programma, punto.


I punti 1-4 sono corretti. Non so nulla del punto 5. Per quanto riguarda il punto finale, una buona applicazione, screen , ti consentirà di consentire l'esecuzione di tutti i processi fino alla loro fine naturale, indipendentemente da come termini la connessione. Lo schermo è nei repository.

La descrizione man dello schermo non è di facile lettura, ma, tra le altre cose, riporta:

Quando viene chiamato screen, crea una singola finestra con una shell al suo interno (o il comando specificato) e quindi si toglie di mezzo in modo che tu possa usare il programma come faresti normalmente. Quindi, in qualsiasi momento, puoi creare nuove finestre (a schermo intero) con altri programmi al loro interno (comprese più shell), chiudere le finestre esistenti, visualizzare un elenco di finestre, attivare e disattivare la registrazione dell'output, copiare e incollare il testo tra finestre, visualizzare la cronologia di scorrimento all'indietro, passare da una finestra all'altra nel modo desiderato, ecc. Tutte le finestre eseguono i loro programmi in modo completamente indipendente l'uno dall'altro.I programmi continuano a essere eseguiti quando la loro finestra non è attualmente visibile e anche quando l'intero schermo la sessione viene scollegata dal terminale dell'utente . Quando un programma termina, screen (per impostazione predefinita) uccide la finestra che lo conteneva. Se questa finestra era in primo piano, la visualizzazione passa alla finestra precedente; se non ne rimane nessuno, lo schermo si chiude.

Ho evidenziato la parte più importante:puoi staccare la finestra con il comando Ctrl+a+d, e poi puoi chiudere/disconnettere la tua sessione, e la finestra ora staccata continuerà a vivere, con i programmi all'interno ancora in esecuzione. Quando ti ricolleghi, ad esempio avviando una nuova sessione ssh, il comando screen -r riprenderà la sessione dello schermo che era stata staccata in precedenza, con tutto l'output dell'errore/output standard chiaramente visibile.


Linux
  1. Quando si digita Ctrl-c in un terminale, perché il lavoro in primo piano non viene terminato fino al completamento?

  2. Quali sono i diversi tipi di shell in Linux?

  3. Qual è il modo corretto per chiudere la mia applicazione PyQt quando viene uccisa dalla console (Ctrl-C)?

  4. Cosa significa la sintassi |&nel linguaggio della shell?

  5. Qual è la differenza tra l'esecuzione di uno script Bash e l'approvvigionamento?

Che cos'è la shell in Linux?

Qual è la differenza tra Login e Non-Login Shell

Rileva il sistema Init usando la shell?

Che cos'è esattamente "un lavoro di arresto", come in "un lavoro di arresto è in esecuzione..."?

Linux:cosa intendiamo esattamente quando diciamo che stiamo usando Linux?

Qual è la differenza tra &> e >&in bash?