Je ne comprends pas la commande bash exec
. J'ai vu qu'il était utilisé à l'intérieur de scripts pour rediriger toute la sortie vers un fichier (comme vu dans este ). Mais je ne comprends pas comment il fonctionne ou ce qu'il fait en général. J'ai lu les pages de manuel mais je ne les comprends pas.
Réponses
Trop de publicités?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.
Les deux dernières lignes sont importantes : si vous exécutez le programme exec
par lui-même, sans commande, il fera simplement en sorte que les redirections s'appliquent au Shell actuel. Vous savez probablement que lorsque vous exécutez command > file
la sortie de command
est écrit dans file
plutôt que vers votre terminal (ceci est appelé un redirection ). Si vous exécutez exec > file
à la place, alors la redirection s'applique à l'ensemble du Shell : Toute sortie produite par le Shell est écrite dans le fichier file
plutôt que vers 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 d'abord un nouveau bash
Shell. Ensuite, dans ce nouveau Shell, j'exécute exec > file
de manière à ce que toutes les sorties soient redirigées vers file
. En effet, après ça, je cours 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 vois que file
contient en effet la sortie du date
que j'ai lancé plus tôt.
exec
est une commande avec deux comportements très distincts, selon qu'au moins un argument est utilisé avec elle, ou qu'aucun argument n'est utilisé du tout.
-
Si au moins un argument est passé, le premier est pris comme un nom de commande et
exec
essayer de l'exécuter comme une commande en passant les arguments restants, s'il y en a, à cette commande et en gérant les redirections, s'il y en a. -
Si la commande passée en premier argument n'existe pas, le Shell actuel, et non seulement le
exec
sort par erreur, à moins que la commande Shell soit interactive ou que l'option bashexecfail
est défini (shopt -s execfail
). Voir aussi https://superuser.com/questions/992204/why-does-exec-non-existent-file-exits-the-Shell-qui-fait-un-Shellqui-est-sourc -
Si la commande existe et est exécutable, elle remplace la Shell actuelle. Cela signifie que si
exec
apparaît dans un script, les instructions suivant l'appel exec ne sera jamais exécuté (à moins queexec
est lui-même dans une sous-couche). Un succèsexec
ne revient jamais. Les pièges de type Shell comme "EXIT" ne seront pas déclenchés non plus. -
Si aucun argument n'est passé,
exec
n'est utilisé que pour redéfinir les descripteurs de fichiers Shell actuels. Le Shell continue après la baliseexec
contrairement au cas précédent, mais l'entrée, la sortie, l'erreur ou le descripteur de fichier standard qui a été redirigé prend effet. -
Si certaines des redirections utilisent
/dev/null
toute entrée en provenance de cet outil renverra EOF et toute sortie vers cet outil sera rejetée. -
Vous pouvez fermer les descripteurs de fichiers en utilisant
-
comme source ou destination, par exempleexec <&-
. Les lectures ou écritures ultérieures é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 va sortir "foo" car la commande cat, au lieu d'attendre l'entrée de l'utilisateur comme elle l'aurait fait dans le cas habituel va prendre 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 va afficher 4
(le nombre d'octets dans /tmp/bar) et se termine immédiatement. Le site cat
ne sera pas exécutée.
Pour comprendre exec
vous devez d'abord comprendre fork
. J'essaie de faire court.
-
Lorsque vous arrivez à une bifurcation sur la route, vous avez généralement deux options. Les programmes Linux atteignent cette bifurcation lorsqu'ils rencontrent une
fork()
appel système. -
Les programmes normaux sont des commandes du système qui existent 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 est appelée bifurcation .
-
La bifurcation permet à un processus existant d'en lancer un nouveau. Cependant, il peut y avoir des situations dans lesquelles un processus enfant ne fait pas partie du même programme que le processus parent. Dans ce cas
exec
est utilisé.exec
remplacera le contenu du processus en cours d'exécution par le fichier informations d'un programme binaire. -
Après le processus de bifurcation, l'espace d'adressage du processus enfant est écrasé avec les données du nouveau processus. Ceci est fait par un appel exec au système.
En bash
si vous le 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 passage pertinent :
If COMMAND is not specified, any redirections take effect in the current shell.
exec
est un Shell builtin qui est l'équivalent Shell de l'icône exec
famille de appels de système que G_P parle de (et dont vous semblez avoir lu les pages de manuel). Il a juste le mandaté par POSIX fonctionnalité d'affecter le Shell actuel si aucune commande n'est spécifiée.