Quelqu'un peut-il expliquer à quoi servent la commande exec dans les scripts shell avec des exemples simples?
Quelqu'un peut-il expliquer à quoi servent la commande exec dans les scripts shell avec des exemples simples?
Réponses:
La execcommande intégrée reflète les fonctions du noyau, il y en a une famille basée sur execve, qui est généralement appelée à partir de C.
execremplace le programme en cours dans le processus en cours, sans forking nouveau processus. Ce n'est pas quelque chose que vous utiliseriez dans chaque script que vous écrivez, mais cela peut être utile à l'occasion. Voici quelques scénarios que je l'ai utilisés;
Nous voulons que l'utilisateur exécute un programme d'application spécifique sans accès au shell. Nous pourrions changer le programme de connexion dans / etc / passwd, mais nous souhaitons peut-être que le paramètre d'environnement soit utilisé à partir des fichiers de démarrage. Donc, dans (disons) .profile, la dernière déclaration dit quelque chose comme:
exec appln-program
alors maintenant, il n'y a pas de shell pour revenir. Même en cas de appln-programplantage, l'utilisateur final ne peut pas accéder à un shell, car il n'est pas là - il l'a execremplacé.
Nous voulons utiliser un shell différent de celui de / etc / passwd. Aussi stupide que cela puisse paraître, certains sites ne permettent pas aux utilisateurs de modifier leur shell de connexion. Un site que je connais a fait démarrer tout le monde csh, et tout le monde vient d' .loginappeler dans leur (fichier de démarrage csh) ksh. Bien que cela ait fonctionné, cela a laissé un cshprocessus errant en cours et la déconnexion était en deux étapes, ce qui pouvait prêter à confusion. Nous l'avons donc changé en exec kshremplaçant simplement le programme c-shell par le korn shell, et rendu tout plus simple (il y a d'autres problèmes avec cela, comme le fait que le kshn'est pas un login-shell).
Juste pour sauver des processus. Si nous appelons prog1 -> prog2 -> prog3 -> prog4etc. et ne revenons jamais en arrière, alors faisons de chaque appel un exécutable. Il économise des ressources (pas beaucoup, certes, sauf répétition) et rend l'arrêt plus simple.
Vous avez évidemment vu executilisé quelque part, peut-être que si vous montriez le code qui vous dérange, nous pourrions justifier son utilisation.
Edit : j'ai réalisé que ma réponse ci-dessus est incomplète. Il y a deux utilisations de execdans des shells comme kshet bash- utilisées pour ouvrir des descripteurs de fichiers. Voici quelques exemples:
exec 3< thisfile # open "thisfile" for reading on file descriptor 3
exec 4> thatfile # open "thatfile" for writing on file descriptor 4
exec 8<> tother # open "tother" for reading and writing on fd 8
exec 6>> other # open "other" for appending on file descriptor 6
exec 5<&0 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4 # copy write file descriptor 4 onto 7
exec 3<&- # close the read file descriptor 3
exec 6>&- # close the write file descriptor 6
Notez que l'espacement est très important ici. Si vous placez un espace entre le nombre fd et le symbole de redirection, puis execrevient à la signification d'origine:
exec 3 < thisfile # oops, overwrite the current program with command "3"
Il y a plusieurs façons dont vous pouvez les utiliser, sur l' utilisation ksh read -uou print -u, sur bash, par exemple:
read <&3
echo stuff >&4
exec gunicornredonne le bon pid au superviseur.
execpeut être utilisé pour la redirection:> Si la commande n'est pas spécifié, aucune redirections prennent effet dans la coquille en cours, et l'état de retour est 0. En cas d'erreur de redirection, l'état de retour est 1. Mais comment fait execfonctionne réellement pour changer un descripteur de fichier? Pourquoi cette commande particulière est-elle choisie pour cette tâche? (Markdown échoue en ce moment?)
exec >.\logfilename.log 2>&1
&>est une bashextension (voir man bash) et votre exemple est équivalent à exec >/var/log/userdata.log 2>&1. En d'autres termes, il redirige stdout et stderr vers ce fichier. Les commandes qui suivent hériteront de ces redirections à moins qu'elles ne soient réinitialisées, mais elles seront exécutées.
Juste pour augmenter la réponse acceptée par une brève réponse courte adaptée aux débutants, vous n'avez probablement pas besoin exec.
Si vous êtes toujours là, la discussion suivante devrait, espérons-le, révéler pourquoi. Quand tu cours, dis,
sh -c 'command'
vous exécutez une shinstance, puis démarrez en commandtant qu'enfant de cette shinstance. Une fois commandterminée, l' shinstance se termine également.
sh -c 'exec command'
exécute une shinstance, puis remplace cette shinstance par le commandbinaire et l'exécute à la place.
Bien entendu, ces deux éléments sont inutiles dans ce contexte limité; tu veux simplement
command
Dans certaines situations marginales, vous souhaitez que le shell lise son fichier de configuration ou, d'une manière ou d'une autre, configure l'environnement comme préparation à l'exécution command. C'est à peu près la seule situation où exec commandest utile.
#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command
Cela fait des choses pour préparer l'environnement afin qu'il contienne ce qui est nécessaire. Une fois cela fait, l' shinstance n'est plus nécessaire, et c'est donc une optimisation (mineure) de simplement remplacer l' shinstance par le commandprocessus, plutôt que de l' shexécuter en tant que processus enfant et de l'attendre, puis de quitter dès qu'elle se termine.
De même, si vous souhaitez libérer autant de ressources que possible pour une commande lourde à la fin d'un script shell, vous pouvez souhaiter execcette commande comme optimisation.
Si quelque chose vous oblige à exécuter shmais que vous vouliez vraiment exécuter autre chose, exec something elsec'est bien sûr une solution de contournement pour remplacer l' shinstance indésirable (comme par exemple si vous vouliez vraiment exécuter votre propre spiffy goshau lieu de shmais le vôtre n'est pas répertorié /etc/shells, vous pouvez donc ne le spécifiez pas comme shell de connexion).
La deuxième utilisation de execpour manipuler les descripteurs de fichiers est un sujet distinct. La réponse acceptée couvre bien cela; pour garder ce contenu autonome, je vais simplement me reporter au manuel pour tout ce qui execest suivi d'une redirection au lieu d'un nom de commande.