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 exec
commande 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.
exec
remplace le programme en cours dans le processus en cours, sans fork
ing 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-program
plantage, l'utilisateur final ne peut pas accéder à un shell, car il n'est pas là - il l'a exec
remplacé.
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' .login
appeler dans leur (fichier de démarrage csh) ksh
. Bien que cela ait fonctionné, cela a laissé un csh
processus errant en cours et la déconnexion était en deux étapes, ce qui pouvait prêter à confusion. Nous l'avons donc changé en exec ksh
remplaç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 ksh
n'est pas un login-shell).
Juste pour sauver des processus. Si nous appelons prog1 -> prog2 -> prog3 -> prog4
etc. 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 exec
utilisé 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 exec
dans des shells comme ksh
et 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 exec
revient à 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 -u
ou print -u
, sur bash
, par exemple:
read <&3
echo stuff >&4
exec gunicorn
redonne le bon pid au superviseur.
exec
peut ê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 exec
fonctionne 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 bash
extension (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 sh
instance, puis démarrez en command
tant qu'enfant de cette sh
instance. Une fois command
terminée, l' sh
instance se termine également.
sh -c 'exec command'
exécute une sh
instance, puis remplace cette sh
instance par le command
binaire 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 command
est 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' sh
instance n'est plus nécessaire, et c'est donc une optimisation (mineure) de simplement remplacer l' sh
instance par le command
processus, plutôt que de l' sh
exé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 exec
cette commande comme optimisation.
Si quelque chose vous oblige à exécuter sh
mais que vous vouliez vraiment exécuter autre chose, exec something else
c'est bien sûr une solution de contournement pour remplacer l' sh
instance indésirable (comme par exemple si vous vouliez vraiment exécuter votre propre spiffy gosh
au lieu de sh
mais 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 exec
pour 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 exec
est suivi d'une redirection au lieu d'un nom de commande.