Pourquoi utiliser «nohup &» plutôt que «exec &»

67

Je sais que, nohupétant un binaire, il est accessible depuis n’importe quel shell. Mais la fonction execintégrée existe probablement dans chaque shell.

Y a-t-il une raison de préférer l'une d'elles à l'autre?

loxaxs
la source

Réponses:

113

Quoi de mieux, un poisson ou un vélo? nohupet execfaire des choses différentes.

execremplace le shell par un autre programme. L'utilisation execdans un travail en arrière-plan simple n'est pas utile: exec myprogram; more stuffremplace le shell par myprogramet ne s'exécute donc pas more stuff, contrairement à celui myprogram; more stuffqui s'exécute more stuffquand se myprogramtermine; mais exec myprogram & more stuffcommence myprogramen arrière-plan et s'exécute more stuff, tout comme myprogram & more stuff.

nohupexécute le programme spécifique avec le signal SIGHUP ignoré. Lorsqu'un terminal est fermé, le noyau envoie SIGHUP au processus de contrôle de ce terminal (c'est-à-dire le shell). Le shell à son tour envoie SIGHUP à tous les travaux exécutés en arrière-plan. L'exécution d'un travail avec nohupempêche celui-ci d'être tué de cette manière si le terminal meurt (ce qui se produit par exemple si vous étiez connecté à distance et si la connexion est interrompue ou si vous fermez votre émulateur de terminal).

nohupredirige également la sortie du programme vers le fichier nohup.out. Cela évite que le programme ne meure car il n'est pas en mesure d'écrire sur sa sortie ou sur une sortie d'erreur. Notez que nohupcela ne redirige pas l'entrée. Pour déconnecter complètement un programme du terminal où vous l'avez lancé, utilisez

nohup myprogram </dev/null >myprogram.log 2>&1 &
Gilles, arrête de faire le mal
la source
27
un vélo> un poisson
Chris Jaynes
6
Je ne suis pas d'accord. Le poisson est évidemment un moyen de transport supérieur s'il peut être mis en œuvre.
CET UTILISATEUR A BESOIN D'AIDE
6
@THISUSERNEEDSHELP Mais un vélo est-il meilleur pour la nourriture?
Gilles 'SO- arrête d'être méchant'
3
@GypsyCosmonaut Après avoir exécuté exec firefoxle shell, celui-ci n'est plus en cours d'exécution: il a été remplacé par firefox. Vous pouvez envisager de execcombiner la sortie d'un programme et le démarrage d'un nouveau programme, tout en conservant le même ID de processus. Le terminal continue à fonctionner car rien ne lui dit de s’arrêter. Lorsque vous quittez Firefox par la suite, le firefoxprocessus se termine. Le terminal remarque que son processus enfant est terminé et qu'il le quitte à son tour.
Gilles 'SO- arrête d'être méchant'
5
Donnez un poisson à un homme et vous le nourrissez pendant une journée. Donnez un vélo à un homme, il pourra aller au supermarché et acheter du poisson toute sa vie.
David
18

exec & => exécute un processus en arrière-plan afin que vous puissiez continuer à utiliser le même terminal pour d'autres tâches.

nohup => évite tout SIGHUP (signal de fin) et continue l'exécution même si votre terminal est fermé.

execle processus meurt quand a SIGHUPest reçu, mais le nohupprocessus continue.

Ani Menon
la source
1
Cette réponse semble être correcte. Comme d'autres réponses ci-dessus le disent, execremplace normalement le processus en cours d'exécution, mais cela ne semble pas se produire lorsque vous utilisez &en arrière-plan la commande exec'd. Ni en bash ni zsh.
Dan Pritts
@DanPritts Que voulez-vous dire par cela ne se produit pas? Un sous-processus d'arrière-plan est démarré puis remplacé, alors exec smth &est-ce la même chose (exec smth) &, n'est-ce pas ce qui se passe?
phk
1
Je veux dire que cela ne soit pas exécuté dans le sens auquel on pourrait normalement penser (remplacer le shell en cours d'exécution) - il est simplement exécuté comme un processus en arrière-plan. Je suppose que c'est probablement le même que (exec smth) &. Mais je ne m'attendrais pas à ce qu'il en soit de même - je m'attendrais à une erreur de syntaxe. Comment pouvez-vous exécuter un processus (en le remplaçant) puis en arrière-plan du processus exécuté? Vous n'êtes plus là pour le faire.
Dan Pritts
2

La commande intégrée exec <command>du shell remplace le shell par <command>aucun nouveau processus, aucun nouveau PID n'est créé. Après l'achèvement de <command>normalement votre terminal sera fermé. En l'exécutant en arrière-plan, un sous-shell est créé, qui est immédiatement remplacé par celui-ci <command>.

La nohup <command> commande sera exécutée <command>mais immume pour raccrocher (kill -s 1) afin qu'elle ne soit pas terminée lorsque le shell, le terminal à partir duquel elle a été démarrée, est fermé. En l'exécutant en arrière-plan, un sous-shell est créé et la commande s'exécute en arrière-plan, ce qui vous ramène à l'invite.

Dans le script, l'effet immédiat est plus ou moins le même, cependant, il <command>est démarré par votre script et le script se poursuivra sans attendre <command>de démarrer, d'envoyer une sortie ou de se terminer.

HBruijn
la source
Moi aussi je ne suis pas sûr de ce que fait l'exécutif. Je veux dire… Je comprends ce que c'est censé faire mais je ne vois qu'une différence mineure entre faire script.sh &ou exec script.sh &. Dans les deux cas, la commande est exécutée dans un processus enfant, elle ne remplace pas le processus d'appel, voir: paste.alacon.org/44474 (trop long pour la copier ici dans un commentaire…). Qu'est-ce que je fais mal?
Stéphane
2

Vous ne pouvez pas comparer nohupavec exec. Lorsque vous exécutez un exécutable avec nohup, le processus ne sera pas tué lorsque vous vous déconnecterez (session ssh); nohupest généralement utilisé avec nicepour exécuter des processus avec une priorité inférieure. Le HUPsignal est, par convention, la façon dont un terminal met en garde les processus dépendants de la déconnexion

utilisateur2660420
la source