Mantenere in esecuzione un processo Linux dopo il logout


142

Mi sto collegando a una macchina Linux tramite SSH e sto cercando di eseguire uno script bash pesante che esegue operazioni sul filesystem. Si prevede che continuerà a funzionare per ore, ma non posso lasciare aperta la sessione SSH a causa di problemi di connessione a Internet che ho.

Dubito che l'esecuzione dello script con l'operatore in background, la e commerciale ( &), farà il trucco, perché l'ho provato e in seguito ho scoperto che il processo non era stato completato. Come posso disconnettermi e mantenere il processo in esecuzione?

Risposte:


135

Il metodo migliore è avviare il processo in un multiplexer terminale. In alternativa è possibile fare in modo che il processo non riceva il segnale HUP.


Un multiplexer terminale fornisce terminali "virtuali" che funzionano indipendentemente dal terminale "reale" (attualmente tutti i terminali sono "virtuali" ma questo è un altro argomento per un altro giorno). Il terminale virtuale continuerà a funzionare anche se il tuo terminale reale è chiuso con la tua sessione SSH.

Tutti i processi avviati dal terminale virtuale continueranno a funzionare con quel terminale virtuale. Quando ti riconnetti al server puoi riconnetterti al terminale virtuale e tutto sarà come se non fosse successo nulla, tranne il tempo che è passato.

Due popolari multiplexer terminali sono screen e tmux .

Lo schermo ha una ripida curva di apprendimento. Ecco un buon tutorial con diagrammi che spiegano il concetto: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


Il segnale HUP (o SIGHUP) viene inviato dal terminale a tutti i suoi processi figlio quando il terminale è chiuso. L'azione comune alla ricezione di SIGHUP è la chiusura. Pertanto, quando la sessione ssh viene disconnessa, tutti i processi verranno chiusi. Per evitare ciò, è possibile impedire ai processi di ricevere SIGHUP.

Due semplici metodi per farlo sono nohupe disown.

Per ulteriori informazioni su come nohupe come disownfunziona leggere questa domanda e rispondere: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

Nota: sebbene i processi continueranno a funzionare, non è più possibile interagire con essi perché non sono più collegati a nessun terminale. Questo metodo è utile principalmente per processi batch di lunga durata che, una volta avviati, non necessitano più di input da parte dell'utente.


3
Mi piace questa risposta in quanto fornisce una soluzione per situazioni sia interattive che non interattive. Nel caso interattivo, screenoffre molte più opzioni, ma se si sta utilizzando authorized_keysper consentire alle persone di eseguire uno script in remoto tramite ssh, l' nohupopzione è un modo semplice per avviare i processi che durano più a lungo della sshsessione utilizzata per avviarli .
Mark Booth,

1
@rahmanisback - Ricorda che puoi modificare la risposta accettata in qualsiasi momento. Solo perché finora la risposta di EricA è stata votata con il massimo dei voti non significa che sia la risposta migliore per te, anzi renderla la tua risposta accettata potrebbe incoraggiare più persone a votarla come una buona risposta.
Mark Booth,

3
* tosse * tmuxisbetter * tosse *
crasico

3
tmux > schermo. Provalo, non ci tornerai mai più.
h0tw1r3,

1
@TheLQ - byobu è GNU Screen. Stai ancora usando lo schermo, solo con un .screenrc altamente personalizzato.
EEAA,

92

Ci sono alcuni modi per farlo, ma quello che trovo più utile è usare GNU Screen .

Dopo aver iniziato, corri screen. Questo avvierà un'altra shell in esecuzione all'interno dello schermo. Esegui il comando, quindi esegui un Ctrl- a d.

Questo ti "disconnetterà" dalla sessione dello schermo. A questo punto, puoi disconnetterti o fare qualsiasi altra cosa tu voglia.

Quando vuoi riconnetterti alla sessione dello schermo, esegui semplicemente screen -RDdal prompt della shell (come lo stesso utente che ha creato la sessione).


6
Lo schermo ha un sacco di comandi, tutti a partire da Ctrl-a. Se ne impari solo uno in più, inizia con "Ctrl-a?". Quindi non imparerai "Ctrl-a c" e "Ctrl-a n"
olafure,

@olafure +1, grazie. Sembra che Screen sarà la mia cassetta degli attrezzi principale.
doc_id,

tmux > schermo. Provalo, non ci tornerai mai più.
h0tw1r3,

+1 per tmux. Ho rinunciato allo schermo 5 settimane fa.
Bryan Hunt,

73

In bash, la disownparola chiave è perfettamente adatta a questo. Innanzitutto, esegui il processo in background (usa &o ^Zpoi digita bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

Digitando jobspuoi vedere che il processo è ancora di proprietà della shell:

$ jobs
[1]+  Running  wget

Se a questo punto dovessi disconnetterti, anche l'attività in background verrebbe uccisa. Tuttavia, se si esegue disown, bash stacca il lavoro e gli consente di continuare l'esecuzione:

$ disown

Puoi confermare questo:

$ jobs
$ logout

Puoi anche combinare &e disownsulla stessa linea, come:

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

Questo è meglio che funzionare nohupsecondo me perché non lascia i nohup.outfile disseminati in tutto il tuo filesystem. Inoltre, nohupdeve essere eseguito prima di eseguire il comando: disownpuò essere utilizzato se in seguito si decide di voler eseguire il background e scollegare l'attività.


1
Questa è un'ottima risposta, 1+. L'unica preferenza per nohup o Screen sarebbe l'indipendenza di bash e potrebbe essere usata con altre shell. Ma mi atterrò al tuo approccio ogni volta che sto usando bash.
doc_id,

Sì, questo è specifico per bash, poiché bash è l'unica shell che abbia mai usato. Mi chiedo se altre shell supportano qualcosa di simile (ovvero il lancio in background senza nohup) - sarebbe fantastico se qualcuno potesse pubblicare altre risposte per altre shell.
Jeremy Visser,

1
vedi la mia risposta che mostra come farlo con qualsiasi sh-sosia
w00t

1
+1 a causa della possibilità di decidere in seguito. Proprio in questo momento ne avevo bisogno. ha funzionato come pubblicizzato
code_monk il

37

Lo strumento nohup, disponibile sulla maggior parte dei box Linux, lo farà.


1
Questa è di gran lunga la risposta più semplice. Qualsiasi output da viene automaticamente indirizzato a nohup.out e può essere esaminato in seguito.
Julian,

3
nohup non richiede affatto zsh.
Aaron Brown,

nohup è la risposta corretta, è l'abbreviazione di nessun riaggancio.
Kinjal Dixit,

2
nohup si trova su molte più macchine rispetto allo schermo, quindi dovresti sapere come usarlo.
Zenon,

27

Per essere precisi , sottolineo tmux , che ha la stessa idea di base dello schermo:

tmux vuole essere una moderna alternativa con licenza BSD a programmi come lo schermo GNU. Le caratteristiche principali includono:

  • Un'interfaccia di comando potente, coerente, ben documentata e facilmente gestibile tramite script.
  • Una finestra può essere suddivisa orizzontalmente e verticalmente in riquadri.
  • I riquadri possono essere spostati e ridimensionati liberamente o disposti in layout predefiniti.
  • Supporto per terminali UTF-8 e 256 colori.
  • Copia e incolla con più buffer.
  • Menu interattivi per selezionare finestre, sessioni o client.
  • Cambia la finestra corrente cercando il testo nella destinazione.
  • Blocco terminale, manuale o dopo un timeout.
  • Una base di codice pulita, facilmente espandibile, con licenza BSD, in fase di sviluppo attivo.

Tuttavia, è quasi infinitamente più facile da cercare su Google.


2
L'uso "gnu screen"come query di ricerca funziona abbastanza bene.
gnur,

4
+1000 per tmux!
mbq,

11

Lo schermo è eccessivo solo per mantenere i processi in esecuzione durante il logout.

Prova dtach :

dtach è un programma scritto in C che emula la funzione di distacco dello schermo, che consente di eseguire un programma in un ambiente protetto dal terminale di controllo. Ad esempio, il programma sotto il controllo di dtach non sarebbe influenzato dalla disconnessione del terminale per qualche motivo.

dtach è stato scritto perché lo schermo non rispondeva adeguatamente alle mie esigenze; Non avevo bisogno delle funzionalità extra dello schermo, come il supporto per più terminali o il supporto dell'emulazione terminale. anche lo schermo era troppo grande, ingombrante e aveva un codice sorgente di difficile comprensione.

lo schermo ha anche interferito con il mio uso di applicazioni a schermo intero come emacs e ircII, a causa della sua eccessiva interpretazione del flusso tra il programma e i terminali collegati. dtach non ha uno strato di emulazione terminale e passa il flusso di output non elaborato del programma ai terminali collegati. L'unica elaborazione di input che dtach esegue è la ricerca del carattere di distacco (che segnala a dach di staccarsi dal programma) e l'elaborazione della chiave di sospensione (che dice a dtach di sospendersi temporaneamente senza influire sul programma in esecuzione), ed entrambi possono essere disabilitato se lo si desidera.

Contrariamente allo schermo, dtach ha funzionalità minime ed è estremamente piccolo. Ciò consente a dtach di essere verificato più facilmente per errori e falle di sicurezza e lo rende accessibile in ambienti in cui lo spazio è limitato, ad esempio sui dischi di ripristino.


Grazie. Sono venuto qui solo per postare su dtach. Adesso è il mio punto di partenza per il distacco terminale; lo schermo MODA troppo e interferisce con l'input in modo ridicolo. Il fatto che lo schermo abbia bisogno del proprio termcap è abbastanza inquietante.
soffice

9

Ecco un modo per demonizzare qualsiasi processo di shell, senza bisogno di programmi esterni:

( while sleep 5; do date; done ) <&- >output.txt &

Quando poi chiudi la sessione, il lavoro continuerà a essere eseguito come evidenziato dal file output.txt (che ha il buffering, quindi ci vuole un po 'per mostrare un valore diverso da zero). Non dimenticare di uccidere il tuo lavoro dopo il test.

Quindi tutto ciò che devi fare è chiudere lo stdin e fare da sfondo al lavoro. Per essere davvero bravi, prima di cd /tutto, non aggrapparti a una cavalcatura.

Funziona anche in modalità sh sotto Solaris.


Interessante. Sono emerse alcune domande importanti. Vedo che hai impostato STDIN su niente, l' -operatore? Qual è la differenza tra < /dev/nulle &-? Immagino che a STDIN (e altri STDOUT e STDERR) possa essere assegnato un file < fileo uno stream <& streamin caso di STDIN. Sarebbe lo stesso usando < /dev/nullnel tuo esempio sopra? E l'operatore -sopra si riferisce a un null come flusso?
doc_id

Quando si esegue x <& -, si chiude il descrittore di file x. In questo caso non è presente alcuna x, che rende di default bash 1, ovvero input standard. Se usi </ dev / null non stai chiudendo stdin, stai solo dando un file vuoto al programma come input.
wt

1
E ad essere sincero, non so davvero perché questo demonizza la cosa che stai eseguendo :-) Funziona però, lo usiamo in produzione. L'ho scoperto mentre scherzavo sperando di poter demonizzare un processo in shell senza aver bisogno di nulla di speciale - quindi ho iniziato chiudendo stdin e questo era abbastanza. Dovrei andare a leggere alcune fonti di shell ma presumo che se si chiude stdin e lo sfondo del processo, si stacca anche il processo.
wt

2
Penso che la ragione sia che un SIGHUP (il segnale effettivo che provoca la chiusura del bambino quando il guscio muore) viene attivato quando un processo genitore chiude la maniglia stdin del figlio. Tuttavia, se stdin inizia come null, anziché essere chiuso dopo il fatto, il genitore non può attivare SIGHUP. Bella scoperta, però, non ci avrei mai pensato.
Jeremy Visser,

@JeremyVisser sembra davvero plausibile!
wt

7

Il atcomando può essere utile per questo tipo di situazione. Ad esempio, digitare:

at now

E puoi quindi inserire un comando o una serie di comandi che verranno eseguiti. I risultati devono essere inviati per e-mail, se l'e-mail è impostata correttamente sulla macchina.

Invece di now, puoi specificare un orario facoltativamente con una data o un'espressione di tempo simile now + 15 minutes. Vedi man atper maggiori dettagli.


7

byobusu Ubuntu è un bel front-end per lo schermo. Premendo Ctrl: ?otterrai un elenco di tutte le scorciatoie da tastiera. Aggiunge una barra di stato che può essere utile per guardare il carico della CPU, lo spazio su disco, ecc. Complessivamente fornisce un'esperienza che descriverei come una connessione VNC basata su terminale.

nohup consente di avviare un lavoro in background con l'output indirizzato a un file di registro, che può sempre essere reindirizzato a / dev / null se non richiesto.

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.