Quelqu’un peut-il expliquer quelles sont les utilisations de la commande exec en script shell avec des exemples simples?
La commande intégrée exec
reflète les fonctions du kernel, il existe une famille basée sur execve
, généralement appelée depuis C.
exec
remplace le programme en cours dans le processus en cours, sans fork
nouveau processus. Ce n’est pas quelque chose que vous utiliseriez dans chaque script que vous écrivez, mais il est utile à l’occasion. Voici quelques scénarios que je l’ai utilisé;
Nous voulons que l’utilisateur exécute un programme d’application spécifique sans access au shell. Nous pourrions changer le programme de connexion dans / etc / passwd, mais peut-être souhaitons-nous utiliser le paramètre d’environnement à partir des fichiers de démarrage. Donc, dans (dis) .profile
, la dernière déclaration dit quelque chose comme:
exec appln-program
alors maintenant il n’y a plus de coquille pour y retourner. Même si le appln-program
bloque, l’utilisateur final ne peut pas accéder à un shell, car il n’y est pas – l’ 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 tout le monde a commencé avec csh
, et tout le monde a juste mis dans leur .login
(fichier de démarrage csh) un appel à ksh
. Bien que cela ait fonctionné, cela a laissé un processus de csh
parasite en cours d’exécution et la déconnexion était en deux étapes, ce qui pouvait être déroutant. Nous l’avons donc changé en exec ksh
qui a simplement remplacé le programme c-shell par le shell korn, et a simplifié tout (il y a d’autres problèmes, comme le fait que le ksh
n’est pas un shell de connexion).
Juste pour enregistrer des processus. Si nous appelons prog1 -> prog2 -> prog3 -> prog4
etc. et ne revenons jamais en arrière, faites chaque appel un exec. Cela économise des ressources (pas beaucoup, certes, à moins de le répéter) et rend la fermeture plus simple.
Vous avez évidemment vu exec
utilisé quelque part, peut-être que si vous monsortingez le code qui vous gêne, nous pourrions justifier son utilisation.
Edit : J’ai réalisé que ma réponse ci-dessus est incomplète. Il existe deux utilisations de exec
dans les shells comme ksh
et bash
– utilisées pour ouvrir les 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, alors exec
revient à la signification d’origine:
exec 3 < thisfile # oops, overwrite the current program with command "3"
Vous pouvez les utiliser de plusieurs manières, sur ksh use read -u
ou print -u
, sur bash
, par exemple:
read <&3 echo stuff >&4
Juste pour compléter la réponse acceptée par une brève réponse brève, vous n’avez probablement pas besoin de exec
.
Si vous êtes toujours là, la discussion qui suit devrait, espérons-le, révéler pourquoi. Lorsque vous courez, disons,
sh -c 'command'
vous exécutez une instance sh
, puis lancez la command
tant qu’enfant de cette instance sh
. Lorsque la command
terminée, l’instance sh
termine également.
sh -c 'exec command'
exécute une instance sh
, puis remplace cette instance sh
par la command
binary et l’exécute à la place.
Bien sûr, les deux sont inutiles dans ce contexte limité; vous voulez simplement
command
Il existe des situations marginales dans lesquelles vous souhaitez que le shell lise son fichier de configuration ou, d’une manière ou d’une autre, configure l’environnement en tant que préparation à l’exécution d’une command
. C’est à peu près la seule situation où la exec command
est utile.
#!/bin/sh ENVIRONMENT=$(some complex task) exec command
Cela permet de préparer l’environnement pour qu’il contienne ce qui est nécessaire. Une fois cela fait, l’instance sh
n’est plus nécessaire et c’est donc une optimisation (mineure) pour remplacer simplement l’instance sh
par le processus de command
, plutôt que de l’exécuter en tant que processus enfant et de l’attendre, puis de quitter comme il 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 exec
cette commande en tant qu’optimisation.
Si quelque chose vous oblige à exécuter sh
mais que vous vouliez vraiment faire autre chose, exécutez quelque exec something else
pour remplacer l’instance sh
indésirable (comme par exemple si vous vouliez vraiment lancer votre propre sposh sur la base de sh
n’est pas répertorié dans /etc/shells
, vous ne pouvez donc pas le spécifier en tant que shell de connexion.
La seconde utilisation de exec
pour manipuler les descripteurs de fichiers est un sujet distinct. La réponse acceptée couvre bien cela; pour que cela rest autonome, je vais juste me reporter au manuel pour tout ce qui est suivi par une redirection au lieu d’un nom de commande.