A volte voglio iniziare un processo e non pensarci più. Se lo avvio dalla riga di comando, in questo modo:
redshift
Non riesco a chiudere il terminale, o ucciderà il processo. Posso eseguire un comando in modo tale da poter chiudere il terminale senza interrompere il processo?
Uno dei seguenti 2 dovrebbe funzionare:
$ Nohup redshift &
o
$ redshift &
$ disown
Vedere di seguito per ulteriori informazioni su come funziona:
man Nohup
help disown
Differenza tra Nohup, disown e & (assicurati di leggere anche i commenti)
Se il tuo programma è già in esecuzione puoi metterlo in pausa con Ctrl-Z
, trascinalo sullo sfondo con bg
e poi disown
, in questo modo:
$ sleep 1000
^Z
[1]+ Stopped sleep 1000
$ bg
$ disown
$ exit
na buona risposta è già pubblicata da @StevenD, ma penso che questo potrebbe chiarire un po 'di più.
Il motivo per cui il processo viene interrotto al termine del terminale è che il processo avviato è un processo figlio del terminale. Una volta chiuso il terminale, questo ucciderà anche questi processi figlio. Puoi vedere l'albero dei processi con pstree
, ad esempio quando esegui kate &
a Konsole:
init-+
├─konsole─┬─bash─┬─kate───2*[{kate}]
│ │ └─pstree
│ └─2*[{konsole}]
Per rendere il processo kate
staccato da konsole
quando si termina konsole
, utilizzare Nohup
con il comando, in questo modo:
Nohup kate &
Dopo aver chiuso konsole
, pstree
sarà simile al seguente:
init-+
|-kate---2*[{kate}]
e kate
sopravviveranno. :)
Un'alternativa sta usando screen
/tmux
/byobu
, che manterrà Shell in esecuzione, indipendentemente dal terminale.
È possibile eseguire il processo in questo modo nel terminale
setsid process
Questo eseguirà il programma in una nuova sessione. Come spiegato http://hanoo.org/index.php?article=run-program-in-new-session-linux
Sebbene tutti i suggerimenti funzionino bene, ho scoperto che la mia alternativa è usare screen
, un programma che imposta un terminale virtuale sullo schermo.
Potresti considerare di avviarlo con screen -S session_name
. Lo schermo può essere installato praticamente su tutti i derivati Linux e Unix. colpire Ctrl+A e (lettere minuscole) C inizierà una seconda sessione. Ciò ti consentirebbe di alternare tra la sessione iniziale e l'altra Ctrl+A e o la sessione più recente colpendo Ctrl+A e 1. Puoi avere fino a dieci sessioni in un terminale. Avviavo una sessione di lavoro, tornavo a casa, ssh nella mia macchina di lavoro, quindi invocavo screen -d -R session_name
. Questo ti riconnetterà a quella sessione remota.
Preferisco:
(nome dell'applicazione e)
ad esempio: [email protected]:~$ (chromium-browser &)
Assicurati di usare le parentesi quando digita il comando!
Ho una sceneggiatura per:
Lo uso principalmente per gedit
, evince
, inkscape
etc che hanno tutti un output terminale fastidioso. Se il comando termina prima di TIMEOUT
, lo stato di uscita di Nohup viene restituito anziché zero.
#!/bin/bash
TIMEOUT=0.1
#use Nohup to run the command, suppressing its output and allowing the terminal to be closed
#also send Nohup's output to /dev/null, supressing Nohup.out
#run Nohup in the background so this script doesn't block
Nohup "${@}" >/dev/null 2>&1 &
Nohup_PID=$!
#kill this script after a short time, exiting with success status - command is still running
#this is needed as there is no timeout argument for `wait` below
MY_PID=$$
trap "exit 0" SIGINT SIGTERM
sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally
#if the command finishes before the above timeout, everything may be just fine or there could have been an error
wait $Nohup_PID
Nohup_STATUS=$?
#print an error if there was any. most commonly, there was a typo in the command
[ $Nohup_STATUS != 0 ] && echo "Error ${@}"
#return the exit status of Nohup, whatever it was
exit $Nohup_STATUS
esempi ...
>>> run true && echo success || echo fail
success
>>> run false && echo success || echo fail
Error false
fail
>>> run sleep 1000 && echo success || echo fail
success
>>> run notfound && echo success || echo fail
Error notfound
fail
Il solo modo di Shell per fare tutto ciò è chiudere stdin e mettere in background il comando:
command <&- &
Quindi non si chiuderà quando si chiude Shell. Il reindirizzamento di stdout è una cosa facoltativa da fare.
Lo svantaggio è che non puoi farlo dopo il fatto.
È possibile impostare un processo (PID) per non ricevere un segnale HUP al momento della disconnessione e della chiusura della sessione del terminale. Utilizzare il comando seguente:
Nohup -p PID
Probabilmente simile al risposta offerta da apolinsky , utilizzo una variante su screen
. Il comando Vanilla è così
screen bash -c 'long_running_command_here; echo; read -p "ALL DONE:"'
La sessione può essere disconnessa con Ctrl ACtrl D e ricollegato nel caso semplice con screen -r
. L'ho racchiuso in uno script chiamato session
che vive nel mio PATH
pronto per un comodo accesso:
#!/bin/bash
#
if screen -ls | awk '$1 ~ /^[1-9][0-9]*\.'"$1"'/' >/dev/null
then
echo "WARNING: session is already running (reattach with 'screen -r $1')" >&2
else
exec screen -S "$1" bash -c "[email protected]; echo; echo '--------------------'; read -p 'ALL DONE (Enter to exit):'"
echo "ERROR: 'screen' is not installed on this system" >&2
fi
exit 1
Funziona solo quando sai in anticipo che vuoi disconnettere un programma. Non prevede la disconnessione di un programma già in esecuzione .
Analogamente ad altre risposte precedentemente pubblicate, è possibile trasferire un processo in esecuzione per utilizzare retrospettivamente lo "schermo" grazie a reptyr e quindi chiudere il terminale. I passaggi sono descritti in questo post . I passi da compiere sono: