Linux: impedisce l’interruzione di un processo in background dopo la chiusura del client SSH

Sto lavorando su una macchina Linux tramite SSH (Putty). Ho bisogno di lasciare un processo in esecuzione durante la notte, quindi ho pensato che avrei potuto farlo avviando il processo in background (con una e commerciale alla fine del comando) e reindirizzando lo stdout su un file. Con mia sorpresa, questo non funziona. Non appena chiudo la finestra Putty, il processo viene interrotto.

Come posso evitare che ciò accada ??

Controlla il programma ” nohup “.

Consiglierei l’uso dello schermo GNU . Ti consente di disconnetterti dal server mentre tutti i tuoi processi continuano a funzionare. Non so come ho vissuto senza di esso prima che io sapevo che esisteva.

Quando la sessione è chiusa, il processo riceve il segnale SIGHUP che apparentemente non sta catturando. È ansible utilizzare il comando nohup all’avvio del processo o il comando built-in bash disown -h dopo l’avvio del processo per evitare che ciò accada:

 > help disown disown: disown [-h] [-ar] [jobspec ...] By default, removes each JOBSPEC argument from the table of active jobs. If the -h option is given, the job is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. The -a option, when JOBSPEC is not supplied, means to remove all jobs from the job table; the -r option means to remove only running jobs. 
 nohup blah & 

Sostituisci il tuo nome di processo per blah!

eseguito come demone? nohup? SCHERMO? (tmux ftw, lo schermo è spazzatura 😉

Basta fare ciò che ha fatto ogni altra app dall’inizio – doppia fork.

 # ((exec sleep 30)&) # grep PPid /proc/`pgrep sleep`/status PPid: 1 # jobs # disown bash: disown: current: no such job 

Scoppio! Fatto 🙂 Ho usato questo innumerevoli volte su tutti i tipi di app e su molte vecchie macchine. È ansible combinare con reindirizzamenti e quant’altro per aprire un canale privato tra te e il processo.

Crea come coproc.sh:

 #!/bin/bash IFS= run_in_coproc () { echo "coproc[$1] -> main" read -r; echo $REPLY } # dynamic-coprocess-generator. nice. _coproc () { local ioen=${1//[^A-Za-z0-9_]}; shift exec {i}<> <(:) {o}<> >(:) {e}<> >(:) . /dev/stdin <&$o 2>&$e $n=( $o $i $e ) COPROC } # pi-rads-of-awesome? for x in {0..5}; do _coproc COPROC$x run_in_coproc $x declare -p COPROC$x done for x in COPROC{0..5}; do . /dev/stdin <&\${$x[1]} read -r -u \${$x[0]}; echo \$REPLY RUN done 

e poi

 # ./coproc.sh declare -a COPROC0='([0]="21" [1]="16" [2]="23")' declare -a COPROC1='([0]="24" [1]="19" [2]="26")' declare -a COPROC2='([0]="27" [1]="22" [2]="29")' declare -a COPROC3='([0]="30" [1]="25" [2]="32")' declare -a COPROC4='([0]="33" [1]="28" [2]="35")' declare -a COPROC5='([0]="36" [1]="31" [2]="38")' coproc[0] -> main COPROC0 <- main coproc[1] -> main COPROC1 <- main coproc[2] -> main COPROC2 <- main coproc[3] -> main COPROC3 <- main coproc[4] -> main COPROC4 <- main coproc[5] -> main COPROC5 <- main 

E tu vai, genera qualunque cosa. il <(:) apre una pipa anonima tramite la sostituzione del processo, che muore, ma la pipa si blocca in giro perché si dispone di una maniglia. Di solito faccio un sleep 1 invece di : perché è leggermente filante, e otterrei un errore "file busy" - non succede mai se viene eseguito un comando reale (ad esempio, command true )

"heredoc sourcing":

 . /dev/stdin < 

Funziona su ogni singola shell che abbia mai provato, incluso busybox / etc (initramfs). Non l'ho mai visto prima, l'ho scoperto indipendentemente mentre lo spronavo, chi sapeva che la fonte poteva accettare args? Ma spesso è una forma molto più gestibile di valutazione, se esiste una cosa del genere.

Personalmente, mi piace il comando “batch”.

 $ batch > mycommand -x arg1 -y arg2 -z arg3 > ^D 

Questo lo inserisce in background, quindi invia i risultati all’utente. Fa parte di cron.

Come altri hanno notato, per eseguire un processo in background in modo che sia ansible disconnettersi dalla sessione SSH, è necessario che il processo in background si disassocia correttamente dal terminale di controllo, che è lo pseudo-tty utilizzato dalla sessione SSH.

Puoi trovare informazioni sui processi di demonizzazione in libri come “Advanced Network Program, Vol 1, 3rd Edn” di Stevens o “Advanced Unix Programming” di Rochkind.

Recentemente (negli ultimi due anni) ho avuto a che fare con un programma recalcitranti che non si è demonizzato correttamente. Ho finito per occuparmene creando un programma di demonizzazione generico, simile a nohup ma con più controlli disponibili.

 Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...] -V print version and exit -a output files in append mode (O_APPEND) -b both output and error go to output file -c create output files (O_CREAT) -d dir change to given directory -e file error file (standard error - /dev/null) -h print help and exit -i file input file (standard input - /dev/null) -k fd-list keep file descriptors listed open -m umask set umask (octal) -o file output file (standard output - /dev/null) -s sig-list ignore signal numbers -t truncate output files (O_TRUNC) -p print daemon PID on original stdout -x output files must be new (O_EXCL) 

Il double-dash è opzionale sui sistemi che non usano la funzione GNU getopt (); è necessario (o devi specificare POSIXLY_CORRECT nell’ambiente) su Linux, ecc. Dal momento che il doppio trattino funziona ovunque, è meglio usarlo.

Puoi comunque contattarmi (nome puntino cognome a gmail punto com) se vuoi che l’origine per daemonize .

Tuttavia, il codice è ora (finalmente) disponibile su GitHub nel mio repository SOQ (Stack Overflow Questions) come file daemonize-1.10.tgz nella daemonize-1.10.tgz dei pacchetti .

Nohup consente a un processo client di non essere ucciso se un processo genitore viene ucciso, per argomento quando si esegue il logout. Ancora meglio ancora utilizzare:

 nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null 

Nohup rende il processo di avvio immuni alla terminazione che la sessione SSH e i suoi processi figli vengono uccisi al momento del logout. Il comando che ho fornito ti fornisce un modo per memorizzare il pid dell’applicazione in un file pid in modo da poterlo uccidere in un secondo momento e consentire al processo di essere eseguito dopo che hai effettuato il logout.

Usa schermo. È molto semplice da usare e funziona come vnc per i terminali. http://www.bangmoney.org/presentations/screen.html

Se si utilizza lo schermo per eseguire un processo come root, fare attenzione alla possibilità di attacchi di elevazione dei privilegi. Se il tuo account viene compromesso in qualche modo, ci sarà un modo diretto per prendere il controllo dell’intero server.

Se questo processo deve essere eseguito regolarmente e si dispone di un accesso sufficiente sul server, un’opzione migliore sarebbe usare cron per eseguire il lavoro. È anche ansible utilizzare init.d (il super-demone) per avviare il processo in background e può terminare non appena viene eseguito.

Su un sistema basato su Debian (sul computer remoto) Installa:

sudo apt-get install tmux

Uso:

tmux

esegui i comandi che desideri

Per rinominare la sessione:

Ctrl + B poi $

imposta nome

Per uscire dalla sessione:

Ctrl + B poi D

(questo lascia la sessione tmux). Quindi, puoi uscire da SSH.

Quando è necessario tornare / controllarlo nuovamente, avviare SSH e immettere

tmux allega session_name

Ti riporterà alla tua sessione di tmux.

nohup è molto buono se vuoi registrare i tuoi dati in un file. Ma quando va in sottofondo non puoi dargli una password se i tuoi script lo richiedono. Penso che tu debba provare lo screen . è una utility che puoi installare sulla tua distribuzione Linux usando yum, ad esempio sulla yum install screen CentOS yum install screen quindi accedi al tuo server tramite putty o un altro software, nella screen tipo di shell. Si aprirà la schermata [0] in stucco. Fai il tuo lavoro Puoi creare più schermo [1], schermo [2], ecc. Nella stessa sessione di mastice.

Comandi di base che devi sapere:

Per avviare la schermata

schermo


Per completare la schermata successiva

ctrl + a + c


Per passare alla schermata n ext creata

Ctrl + A + n


Per esempio

Ctrl + A + D


Durante il lavoro chiudi il tuo mastice. E la prossima volta quando effettui il login tramite il tipo di stucco

schermo -r

Per riconnetterti allo schermo e puoi vedere il tuo processo ancora in esecuzione sullo schermo. E per uscire dal tipo di schermo #exit.

Per maggiori dettagli vedi man screen .

vorrei anche andare per il programma di schermo (so che qualche altra risposta era schermo ma questo è un completamento)

non solo il fatto che &, ctrl + z bg disown, nohup, ecc. può darti una brutta sorpresa che quando ti disconnetti il ​​lavoro sarà comunque ucciso (non so perché, ma è successo a me, e non ha disturbato con questa causa sono passato a usare lo schermo, ma immagino che la soluzione di anthonyrisinger come doppio biforcarsi possa risolverlo), anche lo schermo ha un grande vantaggio rispetto a un semplice back-grounding:

 screen will background your process without losing interactive control to it 

e btw, questa è una domanda che non chiederei mai in primo luogo 🙂 … uso lo schermo del mio inizio di fare qualsiasi cosa in qualsiasi unix … non lavoro quasi mai in una shell unix / linux senza schermata iniziale prima … e dovrei smettere ora, o inizierò una presentazione senza fine di ciò che è buono schermo e cosa può fare per voi … guardate da soli, ne vale la pena;)

C’è anche il comando daemon del pacchetto libslack open-source.

daemon è abbastanza configurabile e si occupa di tutte le noiose cose daemon come il riavvio automatico, la registrazione o la gestione di file pid.

Aggiungi questa stringa al tuo comando:> & – 2> & – <& - &. > & – significa chiudere lo stdout. 2> & – indica close stderr. <& - significa close stdin. & significa eseguire in background. Questo funziona per avviare un lavoro a livello di programmazione tramite SSH:

 $ ssh myhost 'sleep 30 >&- 2>&- <&- &' # ssh returns right away, and your sleep job is running remotely $ 

Per la maggior parte dei processi puoi pseudo-demonizzare usando questo vecchio trucco da riga di comando di Linux:

 # ((mycommand &)&) 

Per esempio:

 # ((sleep 30 &)&) # exit 

Quindi avviare una nuova finestra di terminale e:

 # ps aux | grep sleep 

Mostrerà che il sleep 30 è ancora in esecuzione.

Quello che hai fatto è iniziato il processo come figlio di un bambino, e quando esci, il comando nohup che normalmente innesca l’uscita del processo non scende a cascata verso il nipote, lasciandolo come un processo orfano, ancora in esecuzione.

Preferisco questo approccio “impostalo e dimenticalo”, non c’è bisogno di occuparsi di nohup , screen , tmux, reindirizzamento di I / o, o qualcosa del genere.

Se sei disposto a eseguire anche applicazioni X, usa xpra insieme a “schermo”.

Ho usato il comando schermo. Questo link ha dettagli su come farlo

https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting

La risposta accettata suggerisce di usare nohup . Vorrei piuttosto suggerire l’utilizzo di pm2 . L’utilizzo di pm2 su nohup presenta molti vantaggi, come mantenere triggers l’applicazione, conservare i file di registro per l’applicazione e molte altre funzionalità. Per maggiori dettagli controlla questo .

Per installare pm2 è necessario scaricare npm . Per il sistema basato su Debian

 sudo apt-get install npm 

e per Redhat

 sudo yum install npm 

O puoi seguire queste istruzioni . Dopo aver installato npm, utilizzalo per installare pm2

 npm install [email protected] -g 

Una volta terminato, puoi avviare la tua applicazione entro

 $ pm2 start app.js # Start, Daemonize and auto-restart application (Node) $ pm2 start app.py # Start, Daemonize and auto-restart application (Python) 

Per il monitoraggio del processo, utilizzare i seguenti comandi:

 $ pm2 list # List all processes started with PM2 $ pm2 monit # Display memory and cpu usage of each app $ pm2 show [app-name] # Show all informations about application 

Gestisci i processi utilizzando il nome dell’app o l’id del processo o gestisci tutti i processi insieme:

 $ pm2 stop  $ pm2 restart  $ pm2 delete  

I file di registro possono essere trovati in

 $HOME/.pm2/logs #contain all applications logs 

I file eseguibili binari possono anche essere eseguiti utilizzando pm2. Devi apportare una modifica al file jason. Cambia "exec_interpreter" : "node" , a "exec_interpreter" : "none". (vedi la sezione attributi ).

 #include  #include  //No standard C library int main(void) { printf("Hello World\n"); sleep (100); printf("Hello World\n"); return 0; } 

Compilare sopra il codice

 gcc -o hello hello.c 

ed eseguirlo con np2 in background

 pm2 start ./hello 

Su systemd / Linux, systemd-run è uno strumento utile per avviare processi indipendenti dalla sessione. Odio porta odio