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 ".
Vorrei raccomandare di usare GNU Screen . 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. È 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.
eseguito come demone? nohup? SCHERMO? (tmux ftw, lo schermo è spazzatura ;-)
Fai ciò che ha fatto ogni altra app dall'inizio - doppia forcella.
# ((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. È possibile 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 "${@}"
(("\[email protected]")&) <&$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
E tu vai, genera qualunque cosa. il <(:) apre una pipa anonima tramite la sostituzione del processo, che muore, ma la pipa si blocca perché si dispone di una maniglia. Di solito faccio un sleep 1
invece di :
perché è un po 'spigliato, e otterrei un errore "file busy" - non succede mai se viene eseguito un comando reale (ad esempio, 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 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.
Nohup blah &
Sostituisci il tuo nome di processo per blah!
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 possibile disconnettersi dalla sessione SSH, è necessario che il processo in background si disassocia correttamente dal suo 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 dovuto gestire 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 ancora contattarmi (nome puntino cognome a gmail punto com) se vuoi il sorgente per daemonize
.
Tuttavia, il codice è ora (finalmente) disponibile su GitHub nel mio SOQ (Stack Overflow Questions) repository come file daemonize-1.10.tgz
nel pacchetti sottodirectory.
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 then $
imposta nome
Per uscire dalla sessione:
Ctrl + B then 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 screen
. è una utility che puoi installare sulla tua distribuzione linux usando yum per esempio su CentOS yum install screen
quindi accedi al tuo server tramite PuTTY o un altro software, nel tuo tipo Shell screen
. Si aprirà la schermata [0] in PuTTY. Fai il tuo lavoro È possibile creare più schermo [1], schermo [2], ecc. Nella stessa sessione PuTTY.
Comandi di base che devi sapere:
Per avviare la schermata
Per c reate nella schermata successiva
Per passare a n ext screen che hai creato
A d etach
Durante il lavoro chiudi il tuo PuTTY. E la prossima volta quando effettui il login tramite il tipo PuTTY
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
.
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 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 trattare Nohup
, screen
, tmux, reindirizzamento I/O, o qualcosa del genere.
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 archiviare il pid dell'applicazione in un file pid in modo che tu possa ucciderlo in un secondo momento e che il processo possa essere eseguito dopo che avrai effettuato il logout.
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 possibile utilizzare init.d (il super-demone) per avviare il processo in background e può terminare non appena viene eseguito.
Usa schermo. È molto semplice da usare e funziona come vnc per i terminali. http://www.bangmoney.org/presentations/screen.html
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
$
Se sei disposto a eseguire anche applicazioni X, usa xpra insieme a "schermo".
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.
vorrei anche andare per il programma di schermo (so che un'altra risposta era un'altra schermata, ma questo è un completamento)
non solo il fatto che &, ctrl + z bg disown, Nohup, ecc. possa darti una brutta sorpresa che quando ti disconnetti il lavoro verrà comunque ucciso (non so perché, ma è successo a me, e non si è preoccupato con questa causa sono passato ad usare lo schermo, ma credo che la soluzione di anthonyrisinger come doppio biforcarsi possa risolvere quello), anche lo schermo ha un vantaggio maggiore sul retro -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 un unix/linux Shell 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 ... guardare da soli, ne vale la pena;)
Su systemd/Linux, systemd-run è uno strumento piacevole per avviare processi indipendenti dalla sessione. Odio porta odio
La risposta accettata suggerisce di usare Nohup . Vorrei piuttosto suggerire di usare pm2 . Usare pm2 over Nohup ha molti vantaggi, come mantenere viva l'applicazione, mantenere i file di log 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
Oppure puoi seguire queste istruzioni . Dopo aver installato npm usalo 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 <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 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"
, in "exec_interpreter" : "none".
(vedi la sezione degli 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;
}
Compilare sopra il codice
gcc -o hello hello.c
ed eseguilo con np2 in background
pm2 start ./hello
Ho usato il comando schermo. Questo link ha dettagli su come farlo
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting