Quelles sont les utilisations de la commande exec dans les scripts shell?

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é;

  1. 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é.

  2. 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).

  3. 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.