Je voulais récemment exécuter la commande pkexec
name__, mais j'ai accidentellement réussi à exécuter la commande exec
par elle-même, sans option ni argument. J'ai cherché dans les pages man
la description de exec
name__, mais je n'ai toujours aucune idée de ce que cela signifie:
DESCRIPTION
The exec() family of functions replaces the current process image with
a new process image. The functions described in this manual page are
front-ends for execve(2). (See the manual page for execve(2) for fur‐
ther details about the replacement of the current process image.)
Et en fait, la description continue ... Mais le reste de la description ne m'a pas beaucoup aidé non plus ... C'est donc vraiment ma question: que fait la commande exec
name__? Et est-ce que j'ai fait quelque chose en l'exécutant lui-même sans options ni arguments, tout comme exec
name__? At-il un lien avec la commande pkexec
name__?
"exec()
famille de fonctions" ... sont, ainsi, des fonctions . Ils sont utilisés dans le code source. Ce ne sont pas des commandes à exécuter par les utilisateurs1. Ils sont généralement utilisés par les programmes qui doivent en exécuter un autre (par exemple, le shell lui-même, Sudo
, pkexec
, etc.). Un programme appelant directement exec
se trouvera remplacé par le programme exec
'd; son utilisation typique est donc généralement fork
et exec
.
Un exemple artificiel ressemblerait à ceci:
$ cat foo.c
#include <unistd.h>
int main()
{
const char * path = "/bin/echo";
char * args[] = {"echo", "Hello", "World!", NULL};
execv(path, args);
}
$ gcc -o foo foo.c
$ ./foo
Hello World!
Vous pouvez voir des exemples d'utilisation réelle de exec
à l'aide de strace
dans divers programmes, y compris strace
lui-même:
$ strace -e execve ./foo
execve("./foo", ["./foo"], [/* 52 vars */]) = 0
execve("/bin/echo", ["echo", "Hello", "World!"], [/* 52 vars */]) = 0
Hello World!
+++ exited with 0 +++
Notez que strace
lui-même utilise exec
pour appeler le programme, puis que le programme appelle ensuite exec
.
1 ... sauf pour le exec
Shell intégré , qui est une fonctionnalité du shell.
exec
le shell intégré est semblable aux fonctions exec
dans le sens où l'appel de exec
avec un nom de programme provoque le remplacement du shell par celui-ci. Cependant, l'utilisation courante de exec
est généralement utilisée pour modifier ou ajouter des descripteurs de fichier .
Un autre exemple artificiel:
$ exec 3</dev/urandom
$ read -u 3 -n 10
$ echo "$REPLY" | base64
oZN5Qsn3nAs+1GFUCg==
Vous pourriez penser que nous pourrions lire directement à partir de /dev/urandom
. Oui, nous pourrions. Cependant, cela est utile lorsque:
stdout
dans un fichier pour toute la session Shell).en plus de ce que muru a dit, exec est une commande intégrée de bash. La description suivante est copiée de la page de manuel bash (vous pouvez utiliser 'man bash' pour la voir):
exec [-cl] [-a nom] [commande [arguments]] Si la commande est spécifiée, elle remplace le shell. Aucun nouveau processus n'est créé. Les arguments deviennent Les arguments à commander. Si l'option -l est fournie, le shell place un tiret au début De l'argument zeroth transmis à commande. C'est ce que login (1) fait. L'option -c entraîne l'exécution de com - Mand avec un environnement vide. Si -a est fourni, le shell transmet le nom en tant qu'argument À la commande exécutée. Si la commande ne peut pas être exécutée pour une raison quelconque, un shell interactif non Se ferme, sauf si l'option Shell execfail est activée, auquel cas elle renvoie un échec de . Un shell interactif renvoie un échec si le fichier ne peut pas être exécuté. Si la commande n'est pas spécifiée , Les redirections prennent effet dans le shell actuel et l'état de retour est 0. Si Est une erreur de redirection, l'état de retour est 1.
Pendant que vous exécutiez man exec
, vous avez rencontré la famille de fonctions exec()
qui, en gros, encapsule l’appel système execve(2)
.
Le exec
que vous avez exécuté est un shell intégré:
$ type -a exec
exec is a Shell builtin
Maintenant de help exec
:
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.
Normalement, un nouveau processus est créé par une combinaison d'appels système fork(2)-exec()
. Ici, fork()
créera un processus enfant avec un nouveau PID en dupliquant le processus parent, puis exec()
remplacera le processus enfant par l'exécutable que nous souhaitons exécuter. Par exemple, lorsque nous voulons exécuter un exécutable nommé top
name__, le shell appelle fork(2)
, créant ainsi un processus enfant exactement identique au shell avec un nouveau PID. Ce processus nouvellement créé est remplacé par /usr/bin/top
à l'aide de l'appel exec()
.
Désormais, dans le shell intégré exec
name__, la fork()
n'est pas appelée, mais plutôt exec()
, de sorte que le shell est directement remplacé par l'exécutable et que le nouveau processus hérite du PID du shell.
Notez que seul exec
sans argument ni redirection ne fera rien.