In Linux, come impedire l'arresto di un processo in background dopo la chiusura del client SSH

StackOverflow https://stackoverflow.com/questions/285015

Domanda

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

Come posso evitare che ciò accada ??

È stato utile?

Soluzione

Dai un'occhiata al " nohup " programma.

Altri suggerimenti

Consiglio di utilizzare Schermata GNU . Ti consente di disconnetterti dal server mentre tutti i tuoi processi continuano a essere eseguiti. Non so come ho vissuto senza di essa prima di sapere che esisteva.

Quando la sessione è chiusa, il processo riceve il segnale SIGHUP che apparentemente non sta rilevando. È possibile utilizzare il comando nohup all'avvio del processo o il comando incorporato bash disown -h dopo aver avviato il 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.

demonizzare? nohup? SCHERMO? (tmux ftw, lo schermo è spazzatura ;-)

Fai semplicemente ciò che ogni altra app ha fatto dall'inizio: doppio fork.

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

Bang! Fatto :-) L'ho usato innumerevoli volte su tutti i tipi di app e su molte vecchie macchine. Puoi 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 i o e n=${1//[^A-Za-z0-9_]}; shift
    exec {i}<> <(:) {o}<> >(:) {e}<> >(:)
. /dev/stdin <<COPROC "${@}"
    (("\$@")&) <&$i >&$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 <<RUN
    read -r -u \${$x[0]}; echo \$REPLY
    echo "$x <- main" >&\${$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

Ed ecco fatto, genera qualunque cosa. il < (:) apre una pipe anonima tramite la sostituzione del processo, che muore, ma la pipe si attacca perché hai una maniglia. Di solito faccio un sleep 1 invece di : perché è leggermente vivace, e otterrei un & Quot; file occupato & Quot; errore: non si verifica mai se viene eseguito un comando reale (ad es. command true)

" heredoc sourcing " ;:

. /dev/stdin <<EOF
[...]
EOF

Funziona su ogni singola shell che abbia mai provato, incluso busybox / etc (initramfs). Non l'ho mai visto fare prima, l'ho scoperto in modo indipendente durante il pungolo, chi sapeva che la fonte potesse accettare argomenti? Ma spesso serve come una forma molto più gestibile di valutazione, se esiste una cosa del genere.

nohup blah &

Sostituisci il nome del processo con blah!

Personalmente, mi piace il comando 'batch'.

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

Questo lo inserisce in background e quindi ti spedisce i risultati. Fa parte di cron.

Come altri hanno notato, per eseguire un processo in background in modo da poter disconnettersi dalla sessione SSH, è necessario che il processo in background si dissocia correttamente dal suo terminale di controllo, che è la pseudo-tty che la sessione SSH utilizza.

Puoi trovare informazioni sui processi di demonizzazione in libri come " di Stevens; Advanced Network Program, Vol 1, 3rd Edn " o " di Rochkind; Programmazione Unix avanzata " ;.

Di recente (negli ultimi due anni) ho avuto a che fare con un programma recalcitrante che non si è demonizzato correttamente. Ho finito per affrontarlo 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 doppio trattino è opzionale su sistemi che non usano la funzione getopt () GNU; è necessario (o devi specificare POSIXLY_CORRECT nell'ambiente) su Linux ecc. Dato che il doppio trattino funziona ovunque, è meglio usarlo.

Puoi comunque contattarmi (nome punto punto cognome su gmail punto com) se vuoi la fonte per daemonize.

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

Se si utilizza screen per eseguire un processo come root, fare attenzione alla possibilità di attacchi di elevazione dei privilegi. Se il tuo account viene in qualche modo compromesso, ci sarà un modo diretto per assumere l'intero server.

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

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

  

sudo apt-get install tmux

Utilizzo:

  

tmux

     

esegui i comandi che desideri

Per rinominare la sessione:

  

Ctrl + B quindi $

     

imposta il nome

Per uscire dalla sessione:

  

Ctrl + B quindi D

(questo lascia la sessione di tmux). Quindi, è possibile disconnettersi da SSH.

Quando devi tornare / controllarlo di nuovo, avvia SSH e inserisci

  

tmux attach session_name

Ti riporterà alla tua sessione di tmux.

nohup è molto utile se si desidera registrare i propri dettagli in un file. Ma quando si passa allo sfondo non è possibile assegnargli una password se gli script lo richiedono. Penso che devi provare screen. è un'utilità che puoi installare sulla tua distribuzione Linux usando yum, ad esempio su CentOS yum install screen, quindi accedi al tuo server tramite stucco o altro software, nel tuo tipo di shell man screen. Si aprirà lo schermo [0] in stucco. Fai il tuo lavoro. Puoi creare più schermate [1], schermate [2], ecc. Nella stessa sessione di stucco.

Comandi di base che devi sapere:

Per avviare la schermata

schermata


Per c riattivare la schermata successiva

Ctrl + A + c


Per passare alla n schermata ext che hai creato

Ctrl + A + n


A d etach

Ctrl + A + D


Durante il lavoro chiudi il mastice. E la prossima volta che accedi tramite il tipo di stucco

schermo -r

Per riconnetterti allo schermo e puoi vedere il processo ancora in esecuzione sullo schermo. E per uscire dallo schermo digitare #exit.

Per maggiori dettagli vedi <=>.

Per la maggior parte dei processi è possibile pseudo-daemonize usando questo vecchio trucco da riga di comando di Linux:

# ((mycommand &)&)

Ad esempio:

# ((sleep 30 &)&)
# exit

Quindi avviare una nuova finestra del terminale e:

# ps aux | grep sleep

Mostrerà che sleep 30 è ancora in esecuzione.

Quello che hai fatto è stato avviare il processo come figlio di un bambino, e quando esci, il comando nohup che normalmente farebbe uscire il processo non finisce in cascata verso il nipote, lasciandolo come un processo orfano, ancora in esecuzione.

Preferisco questo " impostalo e dimenticalo " approccio, non è necessario occuparsi di screen, <=>, tmux, reindirizzamento I / o o qualsiasi altra cosa.

Nohup consente di non interrompere un processo client se viene interrotto un processo padre, ad esempio quando si disconnette. Ancora meglio usare ancora:

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

Nohup rende il processo che si avvia immune alla conclusione che la sessione SSH e i suoi processi figlio vengono uccisi al momento della disconnessione. Il comando che ho fornito ti fornisce un modo per archiviare il pid dell'applicazione in un file pid in modo da poterlo uccidere correttamente in seguito e consentire l'esecuzione del processo dopo la disconnessione.

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

Se sei disposto a eseguire anche applicazioni X - usa xpra insieme a " screen < !> quot;.

Vorrei anche scegliere un programma per lo schermo (so che qualcun altro ha risposto allo schermo ma questo è un completamento)

non solo il fatto che & amp ;, ctrl + z bg disown, nohup, ecc. può darti una brutta sorpresa che quando si disconnette il lavoro verrà comunque ucciso (non so perché, ma è successo a me e non si è preoccupato perché sono passato all'utilizzo dello schermo, ma immagino che la soluzione di anthonyrisinger in quanto il doppio fork lo risolva), anche lo schermo ha un vantaggio rispetto al semplice back-grounding:

screen will background your process without losing interactive control to it

e tra l'altro, questa è una domanda che non avrei mai posto in primo luogo :) ... uso lo schermo sin dall'inizio del fare qualsiasi cosa in qualsiasi unix ... io (quasi) non lavoro MAI in una shell unix / linux senza prima avviare lo schermo ... e dovrei fermarmi ora, o inizierò una presentazione infinita di ciò che è buono schermo e cosa può fare per te ... cercalo da solo, ne vale la pena;)

Esiste anche il comando daemon del pacchetto libslack open source.

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

Aggiungi questa stringa al tuo comando: > & amp; - 2 > & amp; - < & amp; - & amp ;. > & amp; - significa vicino stdout. 2 & Gt; & Amp; - significa vicino stderr. < & amp; - significa stretto stdin. & Amp; significa correre in background. Questo funziona anche per avviare un lavoro a livello di codice tramite ssh:

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

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

https://www.rackaid.com / blog / linux-screen dimostrativi-and-how-to / # a partire

La risposta accettata suggerisce di usare nohup . Preferirei suggerire di utilizzare pm2 . L'uso di pm2 su nohup ha molti vantaggi, come mantenere attiva l'applicazione, mantenere i file di registro per l'applicazione e molte altre funzionalità. Per maggiori dettagli consulta questo .

Per installare pm2 devi scaricare npm . Per sistema basato su Debian

sudo apt-get install npm

e per Redhat

sudo yum install npm

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

npm install pm2@latest -g

Al termine, è possibile avviare l'applicazione

$ 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 processo o gestisci tutti i processi insieme:

$ pm2 stop     <app_name|id|'all'|json_conf>
$ pm2 restart  <app_name|id|'all'|json_conf>
$ pm2 delete   <app_name|id|'all'|json_conf>

I file di registro sono disponibili 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", in "exec_interpreter" : "none". (vedi la sezione attributi ).

#include <stdio.h>
#include <unistd.h>  //No standard C library
int main(void)
{
    printf("Hello World\n");
    sleep (100);
    printf("Hello World\n");

    return 0;
}

Compilazione sopra il codice

gcc -o hello hello.c  

ed eseguilo con np2 in background

pm2 start ./hello

Su systemd / Linux, systemd-run è uno strumento utile per avviare processi indipendenti dalla sessione. Gli odiatori odieranno

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top