Comment puis-je fermer un terminal sans tuer la command en cours d'exécution?

Parfois, je veux commencer un process et l'oublier. Si je le lance depuis la command line, comme ceci:

redshift 

Je ne peux pas fermer le terminal, ou il va tuer le process. Puis-je exécuter une command de manière à pouvoir fermer le terminal sans tuer le process?

L'un des 2 suivants devrait fonctionner:

 $ nohup redshift & 

ou

 $ redshift & $ disown 

Voir ce qui suit pour un peu plus d'informations sur la façon dont cela fonctionne:

  • man nohup

  • help disown

  • Différence entre nohup, renie et & (veillez à lire les commentaires aussi)

Si votre programme est déjà en cours d' exécution, vous pouvez le mettre en pause avec Ctrl-Z , le tirer en arrière-plan avec bg et le disown , comme ceci:

 $ sleep 1000 ^Z [1]+ Stopped sleep 1000 $ bg $ disown $ exit 

Bonne réponse est déjà posté par @StevenD, mais je pense que cela pourrait clarifier un peu plus.

La raison pour laquelle le process est tué à la fin du terminal est que le process que vous démarrez est un process enfant du terminal. Une fois que vous fermez le terminal, cela va également tuer ces process enfants. Vous pouvez voir l'tree de process avec pstree , par exemple en exécutant kate & dans Konsole:

 init-+ ├─konsole─┬─bash─┬─kate───2*[{kate}] │ │ └─pstree │ └─2*[{konsole}] 

Pour rendre le process kate détaché de konsole lorsque vous konsole , utilisez nohup avec la command, comme ceci:

 nohup kate & 

Après la fermeture de konsole , pstree ressemblera à ceci:

 init-+ |-kate---2*[{kate}] 

et le kate survivra. 🙂

Une alternative consiste à utiliser screen / tmux / byobu , ce qui permettra au shell de fonctionner indépendamment du terminal.

Vous pouvez exécuter le process comme ceci dans le terminal

setsid process

Cela exécutera le programme dans une nouvelle session. Comme expliqué http://hanoo.org/index.php?article=run-program-in-new-session-linux

J'ai un script pour:

  • Exécuter des commands arbitraires en arrière-plan

  • Empêchez-les d'être tués avec la window du terminal

  • Supprimer leur sortie

  • Gère le statut de sortie

Je l'utilise principalement pour gedit , inkscape , inkscape etc qui ont tous beaucoup de sortie de terminal ennuyeux. Si la command se termine avant TIMEOUT , l'état de sortie de nohup est renvoyé au lieu de zéro.

 #!/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 

exemples…

 >>> 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 

La seule manière de faire tout cela est de fermer stdin et d'arrière-plan la command:

 command <&- & 

Ensuite, il ne quittera pas lorsque vous quittez le shell. Rediriger stdout est une bonne chose optionnelle à faire.

Le désavantage est que vous ne pouvez pas le faire après le fait.

Bien que toutes les suggestions fonctionnent bien, j'ai trouvé mon alternative est d'utiliser l' screen , un programme qui configure un terminal virtuel sur votre écran.

Vous pourriez envisager de le démarrer avec l' screen -S session_name . Screen peut être installé sur pratiquement tous les dérivés Linux et Unix. En appuyant sur Ctrl + A et (minuscule) C commencera une deuxième session. Cela vous permet de basculer entre la session initiale en appuyant sur Ctrl + A et 0 ou la session plus récente en appuyant sur Ctrl + A et 1 . Vous pouvez avoir jusqu'à dix sessions dans un terminal. Je commençais une session au travail, je rentrais chez moi, ssh dans ma machine de travail, puis j'appelais screen -d -R session_name . Cela vous reconnectera à cette session distante.

Vous pouvez définir un process (PID) pour ne pas recevoir un signal HUP lors de la déconnection et la fermeture de la session du terminal. Utilisez la command suivante:

 nohup -p PID 

Vous pouvez utiliser un multiplexeur d'écran tel que tmux . Il est disponible via apt-get sur les machines ubuntu

Sans doute semblable à la réponse offerte par apolinsky , j'utilise une variante à l' screen . La command de vanille est comme ça

 screen bash -c 'long_running_command_here; echo; read -p "ALL DONE:"' 

La session peut être déconnectée avec Ctrl A Ctrl D et reconnectée dans le cas simple avec screen -r . Je l'ai enveloppé dans un script appelé session qui vit dans mon PATH prêt pour un access pratique:

 #!/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 "$@; echo; echo '--------------------'; read -p 'ALL DONE (Enter to exit):'" echo "ERROR: 'screen' is not installed on this system" >&2 fi exit 1 

Cela ne fonctionne que lorsque vous savez à l'avance que vous souhaitez déconnecter un programme. Il ne prévoit pas qu'un programme déjà en cours soit déconnecté.

Je préfère:

(Nom de l'application &)

par exemple: linux@linux-desktop:~$ (chromium-browser &)

Assurez-vous d'utiliser des parenthèses lorsque vous tapez la command!