362 votes

Comment détacher entièrement un processus de Terminal ?

J'utilise Tilda (terminal déroulant) sur Ubuntu comme ma "centrale de commande" - à peu près comme d'autres pourraient utiliser GNOME Do, Quicksilver ou Launchy.

Cependant, je ne sais pas comment détacher complètement un processus (par exemple Firefox) du terminal à partir duquel il a été lancé, c'est-à-dire empêcher qu'un tel processus (non-)enfant

  • se termine par la fermeture du terminal d'origine
  • "pollue" le terminal d'origine via STDOUT/STDERR

Par exemple, afin de démarrer Vim dans une fenêtre de terminal "correcte", j'ai essayé un simple script comme le suivant :

exec gnome-terminal -e "vim $@" &> /dev/null &

Cependant, cela entraîne toujours une pollution (de même, le fait de passer un nom de fichier ne semble pas fonctionner).

1 votes

C'est aussi une bonne question. Je pense qu'il est juste de considérer Bash comme un langage de programmation - bien que la portée de cette question soit probablement plus du côté des administrateurs système...

0 votes

Il s'agit d'un duplicata de cette question stackoverflow.com/questions/285015/

0 votes

418voto

hamo Points 739

Tout d'abord, une fois que vous avez lancé un processus, vous pouvez le mettre en arrière-plan en l'arrêtant d'abord (appuyez sur Ctrl - Z ) et ensuite taper bg pour le laisser reprendre en arrière-plan. C'est maintenant un "travail", et son stdout / stderr / stdin sont toujours connectés à votre terminal.

Vous pouvez lancer un processus en arrière-plan immédiatement en ajoutant un "&" à sa fin :

firefox &

Pour le faire fonctionner en arrière-plan en silence, utilisez ceci :

firefox </dev/null &>/dev/null &

Quelques informations supplémentaires :

nohup est un programme que vous pouvez utiliser pour exécuter votre application avec de sorte que son stdout/stderr puisse être envoyé à un fichier à la place et de sorte que la fermeture du script parent ne SIGHUPera pas l'enfant. Cependant, vous devez avoir eu la prévoyance de l'utiliser avant de lancer l'application. En raison de la manière dont nohup fonctionne, tu ne peux pas juste l'appliquer à un processus en cours .

disown est un buildin bash qui supprime un travail Shell de la liste des travaux du Shell. Ce que cela signifie fondamentalement, c'est que vous ne pouvez pas utiliser la fonction fg , bg mais surtout, lorsque vous fermez votre Shell, il ne se bloque pas et n'envoie pas de message d'erreur. SIGHUP à cet enfant. Contrairement à nohup , disown est utilisé après le processus a été lancé et mis en arrière-plan.

Ce que vous ne peut pas faire, c'est changer le stdout/stderr/stdin d'un processus après l'avoir lancé. Du moins pas depuis le Shell. Si vous lancez votre processus et lui dites que son stdout est votre terminal (ce que vous faites par défaut), alors ce processus est configuré pour sortir sur votre terminal. Votre Shell n'a rien à voir avec la configuration FD des processus, c'est purement quelque chose que le processus lui-même gère. Le processus lui-même peut décider de fermer ou non son stdout/stderr/stdin, mais vous ne pouvez pas utiliser votre Shell pour le forcer à le faire.

Pour gérer la sortie d'un processus d'arrière-plan, vous disposez de nombreuses options parmi scripts, "nohup" étant probablement la première à venir à l'esprit. Mais pour les processus interactifs que vous lancez mais que vous avez oublié de faire taire ( firefox < /dev/null &>/dev/null & ) vous ne pouvez pas faire grand chose, vraiment.

Je vous recommande d'obtenir GNU screen . Avec screen, vous pouvez simplement fermer votre Shell en cours d'exécution lorsque la sortie du processus devient gênante et en ouvrir un nouveau ( ^Ac ).


Oh, et au fait, n'utilisez pas " $@ "où vous l'utilisez.

$@ signifie, $1 , $2 , $3 ..., ce qui transformerait votre commande en :

gnome-terminal -e "vim $1" "$2" "$3" ...

Ce n'est probablement pas ce que vous voulez parce que -e prend seulement un argument. Utilisez $1 pour montrer que votre script ne peut gérer qu'un seul argument.

Il est vraiment difficile de faire fonctionner correctement des arguments multiples dans le scénario que vous avez donné (avec la fonction gnome-terminal -e ) car -e ne prend qu'un seul argument, qui est une chaîne de commande Shell. Vous devriez coder vos arguments en un seul. La meilleure et la plus robuste, mais plutôt maladroite, méthode est la suivante :

gnome-terminal -e "vim $(printf "%q " "$@")"

0 votes

Merci beaucoup pour cela ! Malheureusement, je ne peux accepter qu'une seule réponse. Je me suis retrouvé avec "nohup $@ &> /dev/null &" et "alias wvim='launch.sh gnome-terminal -x vim'".

0 votes

Bizarre : quand je fais "Ctrl-z" dans le terminal, et ensuite "bg", le processus ne devrait plus dépendre du terminal. Mais quand j'ai fermé le terminal, il a été fermé aussi o.O.

1 votes

@Hi-Angel lorsque vous fermez une bash Shell interactive, bash HUPs tous les travaux actifs. Lorsque vous ^Z et bg un processus, c'est toujours un travail, même en arrière-plan. Pour le supprimer en tant que travail, utilisez disown alors le processus continuera à vivre après que vous ayez fermé le Shell puisque bash ne le HUPera plus.

229voto

dsm Points 2399
nohup cmd &

nohup détache complètement le processus (le démonise)

6 votes

Si la concision est précieuse, l'exhaustivité l'est davantage. Bien que nohup soit un coreutil GNU, une réponse uniquement bash (ou une note sur le fait qu'il n'y en a pas) serait appropriée ici. Bonne réponse néanmoins.

33 votes

nohup ignore simplement le SIGHUP signal. Il exécute le processus normalement. Pas de démonisation.

2 votes

@nemo Ce qui signifie que le processus n'est pas détaché, mais qu'il le deviendrait (et qu'il deviendrait un enfant de l'entreprise). init ) si le Shell sortait... n'est-ce pas ?

74voto

configurator Points 123

Si vous utilisez bash essayez. disown [_jobspec_] ; voir bash(1) .

Une autre approche que vous pouvez essayer est at now . Si vous n'êtes pas superutilisateur, votre permission d'utiliser at peuvent être limitées.

0 votes

"disown" ne semble pas être une commande bash interne (non disponible sur ma machine, et j'utilise bash). "nohup", comme Ben l'a suggéré, pourrait être une bien meilleure (et standard) façon de faire cela.

2 votes

at de déléguer l'exécution à quelqu'un d'autre, j'aime ça ! +1

1 votes

À titre de référence, cela fonctionne dans zsh également.

37voto

Mr. Minty Fresh Points 559
  1. nohup $COMMAND &
  2. $COMMAND & disown
  3. setsid command

J'utilise le numéro 2 depuis très longtemps, mais le numéro 3 fonctionne tout aussi bien. Aussi, disown a un nohup drapeau de -h peut désactiver tous les processus avec -a et peut désactiver tous les processus en cours avec -ar .

Le silence est accompli par $COMMAND &>/dev/null .

J'espère que cela vous aidera !

0 votes

Merci pour ce résumé très utile !

0 votes

Je n'arrive pas à croire que je reçoive encore des notifications pour ce message...

14voto

ManuelSchneid3r Points 913

La réponse la plus simple et la seule correcte pour bash :

command & disown

Vous ne devez pas détacher le processus du terminal, mais du Shell.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X