web-dev-qa-db-fra.com

Que fait une commande "exec"?

Je ne comprends pas la commande bash exec. Je l'ai vu utilisé dans des scripts pour rediriger toutes les sorties vers un fichier (comme indiqué dans this ). Mais je ne comprends pas comment ça marche ou ce que ça fait en général. J'ai lu les pages de manuel mais je ne les comprends pas.

94
becko

man bash dit:

exec [-cl] [-a name] [command [arguments]]
      If command is specified, it replaces the Shell.  No new  process
      is  created.  The arguments become the arguments to command.  If
      the -l option is supplied,  the  Shell  places  a  dash  at  the
      beginning  of  the  zeroth  argument passed to command.  This is
      what login(1) does.  The -c option causes command to be executed
      with  an empty environment.  If -a is supplied, the Shell passes
      name as the zeroth argument to the executed command.  If command
      cannot  be  executed  for  some  reason, a non-interactive Shell
      exits, unless the execfail Shell option  is  enabled.   In  that
      case,  it returns failure.  An interactive Shell returns failure
      if the file cannot be executed.  If command  is  not  specified,
      any  redirections  take  effect  in  the  current Shell, and the
      return status is 0.  If there is a redirection error, the return
      status is 1.

Ce qui est important, ce sont les deux dernières lignes: si vous exécutez exec seul, sans commande, les redirections s’appliqueront simplement au Shell en cours. Vous savez probablement que lorsque vous exécutez command > file, la sortie de command est écrite dans file au lieu de sur votre terminal (cette opération s'appelle une redirection ). Si vous exécutez plutôt exec > file, la redirection s'applique à l'ensemble du shell: toute sortie produite par le shell est écrite dans file au lieu de celle de votre terminal. Par exemple ici

bash-3.2$ bash
bash-3.2$ exec > file
bash-3.2$ date
bash-3.2$ exit
bash-3.2$ cat file
Thu 18 Sep 2014 23:56:25 CEST

Je commence par un nouveau shell bash. Ensuite, dans ce nouveau shell, j'exécute exec > file, de sorte que toute la sortie soit redirigée vers file. En effet, après cela, je lance date mais je n’obtiens aucune sortie, car la sortie est redirigée vers file. Ensuite, je quitte mon shell (pour que la redirection ne s'applique plus) et je constate que file contient en effet le résultat de la commande date que j'ai exécutée précédemment.

76
fkraiem

exec est une commande avec deux comportements très distincts, selon qu’au moins un argument est utilisé avec elle ou pas du tout.

  • Si au moins un argument est passé, le premier est utilisé comme nom de commande et exec tente de l'exécuter en tant que commande, en transmettant les arguments restants, le cas échéant, à cette commande et en gérant les redirections, le cas échéant.

  • Si la commande passée en tant que premier argument n'existe pas, le shell actuel, et pas seulement la commande exec, se termine en erreur.

  • Si la commande existe et qu'elle est exécutable, elle remplace le shell actuel. Cela signifie que si exec apparaît dans un script, les instructions qui suivent l'appel exec ne sera jamais exécuté (sauf si exec est lui-même dans un sous-shell). exec ne retourne jamais. Les pièges tels que "EXIT" ne seront pas déclenchés non plus.

  • Si aucun argument n'est passé, exec sert uniquement à redéfinir les descripteurs de fichier Shell actuels. Le shell continue après le exec, contrairement au cas précédent, mais l'entrée standard, la sortie, l'erreur ou tout autre descripteur de fichier redirigé prend effet.

  • Si certaines des redirections utilisent /dev/null, toute entrée de celle-ci renverra EOF et toute sortie y figurant sera supprimée.

  • Vous pouvez fermer les descripteurs de fichier en utilisant - comme source ou destination, par exemple. exec <&-. Les lectures ou écritures suivantes échoueront alors.

Voici deux exemples:

echo foo > /tmp/bar
exec < /tmp/bar # exec has no arguments, will only affect current Shell descriptors, here stdin
cat # simple command that read stdin and write it to stdout

Ce script affichera "foo" en tant que commande cat, au lieu d'attendre la saisie de l'utilisateur, comme cela aurait été le cas habituel, prendra son entrée dans le fichier/tmp/bar qui contient foo.

echo foo > /tmp/bar
exec wc -c < /tmp/bar # exec has two arguments, the control flow will switch to the wc command
cat

Ce script affiche 4 (le nombre d'octets dans/tmp/bar) et se termine immédiatement. La commande cat ne sera pas exécutée.

39
jlliagre

Pour comprendre execvous devez d'abord comprendre forkname__. J'essaie de rester bref.

  • Lorsque vous arrivez à un embranchement, vous avez généralement deux options. Les programmes Linux atteignent cette fourchette lorsqu'ils lancent un appel système fork().

  • Les programmes normaux sont des commandes système existant sous une forme compilée sur votre système. Lorsqu'un tel programme est exécuté, un nouveau processus est créé. Ce processus enfant a le même environnement que son parent, seul le numéro d'identification du processus est différent. Cette procédure s'appelle forking.

  • Forking fournit un moyen pour un processus existant de démarrer un nouveau. Cependant, il peut y avoir des situations où un processus enfant ne fait pas partie du même programme que le processus parent. Dans ce cas, execest utilisé. execremplacera le contenu du processus en cours d'exécution par les informations d'un programme binaire.
  • Après le processus de forking, l'espace d'adressage du processus enfant est écrasé par les nouvelles données de processus. Cela se fait par un appel exec au système.
30
g_p

Dans bash, si vous faites help exec:

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the Shell with the given command.

    Execute COMMAND, replacing this Shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current Shell.

    Options:
      -a name   pass NAME as the zeroth argument to COMMAND
      -c        execute COMMAND with an empty environment
      -l        place a dash in the zeroth argument to COMMAND

    If the command cannot be executed, a non-interactive Shell exits, unless
    the Shell option `execfail' is set.

    Exit Status:
    Returns success unless COMMAND is not found or a redirection error occurs.

Le bit pertinent:

If COMMAND is not specified, any redirections take effect in the current Shell.

exec est un Shell intégré , qui est l'équivalent Shell de la famille exec de appels système dont G_P en parle (et dont vous paraissez la page de manuel ont lu). Il a juste la fonctionnalité POSIX mandaté d’affecter le shell actuel si aucune commande n’est spécifiée.

6
muru