Quelle est la différence entre le nohup et l'esperluette

243

Les deux nohup myprocess.out &ou myprocess.out &définissez myprocess.out pour qu'il s'exécute en arrière-plan. Après avoir arrêté le terminal, le processus est toujours en cours d'exécution. Quelle est la différence entre eux?

Yarkee
la source
quel shell utilisez-vous? le comportement varie selon les obus
shx2
1
frapper. Et je sais pourquoi maintenant selon la réponse de @nemo.
Yarkee
@Yarkee si la réponse convient à votre problème, veuillez marquer la question comme acceptée (la case à cocher sous les votes de la réponse) afin qu'elle ne reste pas sans réponse. Vous devriez le faire pour toutes vos questions :)
nemo
1
shutdowndevrait être évité en tant que terme ayant une signification Linux spécifique., et être remplacé par exit.
Patrizio Bertoni

Réponses:

317

nohupattrape le signal de raccrochage (voir man 7 signal) alors que l'esperluette ne le fait pas (sauf que le shell est configuré de cette façon ou n'envoie pas SIGHUPdu tout).

Normalement, lors de l'exécution d'une commande utilisant &et quittant le shell par la suite, le shell terminera la sous-commande avec le signal de raccrochage ( kill -SIGHUP <pid>). Cela peut être évité à l'aide nohup, car il capture le signal et l'ignore afin qu'il n'atteigne jamais l'application réelle.

Dans le cas où vous utilisez bash, vous pouvez utiliser la commande shopt | grep huponpour savoir si votre shell envoie SIGHUP à ses processus enfants ou non. S'il est désactivé, les processus ne seront pas interrompus, comme cela semble être le cas pour vous. Vous trouverez plus d'informations sur la façon dont bash termine les applications ici .

Il y a des cas où nohupcela ne fonctionne pas, par exemple lorsque le processus que vous démarrez reconnecte le SIGHUPsignal, comme c'est le cas ici .

nemo
la source
Il peut être intéressant de noter que &la sous-commande ne reçoit tout simplement pas certains signaux (par exemple SIGINT). nohupajoute essentiellement SIGHUPà la liste des signaux qui ne sont pas propagés.
studgeek
46

myprocess.out &exécuterait le processus en arrière-plan à l'aide d'un sous-shell. Si le shell actuel est terminé (par exemple par déconnexion), tous les sous-coquilles sont également terminés de sorte que le processus d'arrière-plan serait également terminé. La commande nohup ignore le HUPsignal et donc même si le shell actuel est terminé, le sous-shell et myprocess.outcontinuerait de s'exécuter en arrière-plan. Une autre différence est que &seul ne redirige pas stdout / stderr donc s'il y a une sortie ou une erreur, celles-ci sont affichées sur le terminal. nohup d'autre part redirige le stdout / stderr vers nohup.outou $HOME/nohup.out.

amit_g
la source
6
Je cours myprocess.out &et quitte le shell. Cependant, lorsque j'utilise ps aux | grep myprocess.outdans un autre shell, je peux toujours trouver "myprocess.out". Cela signifie que le processus est toujours en cours, ne pas être interrompu.
Yarkee
1
@amit_g Lors de la suppression du shell parent avec kill -9il n'y aura pas de SIGHUP car cela nécessiterait que le shell parent gère SIGKILL, ce qu'il ne peut pas.
nemo
2
Vérifiez shopt | grep hupon comme mentionné dans l'autre réponse.
amit_g
31

La plupart du temps, nous nous connectons au serveur distant à l'aide de ssh. Si vous démarrez un script shell et que vous vous déconnectez, le processus est interrompu. Nohup permet de continuer à exécuter le script en arrière-plan même après vous être déconnecté du shell.

Nohup command name &
eg: nohup sh script.sh &

Nohup capte les signaux HUP. Nohup ne met pas automatiquement le travail en arrière-plan. Nous devons dire que l'utilisation explicite de &

missgeorge
la source
Merci. Je n'attendais pas votre réponse mais le fait qu'elle soit ici est génial. Il répond à la question que je n'ai pas posée: D
Vaibhav Kaushal
26

L'utilisation de l'esperluette (&) exécutera la commande dans un processus enfant (enfant à la session bash en cours). Cependant, lorsque vous quittez la session, tous les processus enfants seront supprimés.

l'utilisation de nohup + esperluette (&) fera la même chose, sauf qu'à la fin de la session, le parent du processus enfant sera changé en "1" qui est le processus "init", préservant ainsi l'enfant d'être tué.

Michel
la source
7

Corrige moi si je me trompe

  nohup myprocess.out &

nohup intercepte le signal de raccrochage, ce qui signifie qu'il enverra un processus lorsque le terminal sera fermé.

 myprocess.out &

Le processus peut s'exécuter mais s'arrêtera une fois le terminal fermé.

nohup myprocess.out

Processus capable d'exécuter même le terminal fermé, mais vous pouvez arrêter le processus en appuyant sur ctrl+ zdans le terminal. Crt+ zne fonctionne pas s'il &existe.

John Joe
la source
2

La commande nohup est un utilitaire de masquage de signal et intercepte le signal de raccrochage. Où l'esperluette n'attrape pas les signaux de raccrochage. Le shell terminera la sous-commande avec le signal de raccrochage lors de l'exécution d'une commande en utilisant & et en quittant le shell. Cela peut être évité en utilisant nohup, car il capte le signal. La commande Nohup accepte le signal de raccrochage qui peut être envoyé à un processus par le noyau et les bloquer. La commande Nohup est utile lorsqu'un utilisateur souhaite démarrer une déconnexion d'application longue durée ou fermer la fenêtre dans laquelle le processus a été lancé. L'une ou l'autre de ces actions invite normalement le noyau à raccrocher sur l'application, mais un wrapper nohup permettra au processus de continuer. L'utilisation de l'esperluette exécutera la commande dans un processus enfant et cet enfant de la session bash en cours. Lorsque vous quittez la session, tous les processus enfants de ce processus seront tués. L'esperluette concerne le contrôle des travaux pour la coque active. Ceci est utile pour exécuter un processus dans une session en arrière-plan.

Santosh
la source
0

Il existe de nombreux cas où de petites différences entre les environnements peuvent vous mordre. C'est celui que j'ai rencontré récemment. Quelle est la différence entre ces deux commandes?

1 ~ $ nohup myprocess.out &
2 ~ $ myprocess.out &

La réponse est la même que d'habitude - cela dépend.

nohup intercepte le signal de raccrochage, contrairement à l'esperluette.

Quel est le signal de raccrochage?

SIGHUP - raccrochage détecté sur le terminal de contrôle ou arrêt du processus de contrôle (valeur: 1).

Normalement, lors de l'exécution d'une commande en utilisant & et en quittant le shell par la suite, le shell terminera la sous-commande avec le signal de raccrochage (comme kill -SIGHUP $ PID). Cela peut être évité en utilisant nohup, car il capte le signal et l'ignore afin qu'il n'atteigne jamais l'application réelle.

Très bien, mais comme dans ce cas, il y a toujours des «mais». Il n'y a aucune différence entre ces méthodes de lancement lorsque le shell est configuré de manière à ne pas envoyer SIGHUP du tout.

Dans le cas où vous utilisez bash, vous pouvez utiliser la commande spécifiée ci-dessous pour savoir si votre shell envoie SIGHUP à ses processus enfants ou non:

~ $ shopt | grep hupon

Et en plus - il y a des cas où nohup ne fonctionne pas. Par exemple, lorsque le processus que vous démarrez reconnecte le signal NOHUP (cela se fait à l'intérieur, au niveau du code d'application).

Dans le cas décrit, le manque de différences m'a mordu quand à l'intérieur d'un script de lancement de service personnalisé, il y avait un appel à un deuxième script qui configure et lance l'application appropriée sans commande nohup.

Dans un environnement Linux, tout s'est bien passé, dans un second, l'application s'est arrêtée dès que le deuxième script est sorti (détecter ce cas, bien sûr, m'a pris beaucoup plus de temps que vous ne le pensez: stuck_out_tongue :).

Après avoir ajouté nohup comme méthode de lancement au deuxième script, l'application continue de fonctionner même si les scripts se terminent et ce comportement est devenu cohérent sur les deux environnements.

Devender Goyal
la source