试图了解 execvp 的工作原理
Trying to understand how execvp works
我在execvp
上找到了很多解释和答案,但看起来都很混乱。 execvp
获取命令并将其发送到内核然后执行某些操作,execvp
创建图像,execvp
是系统调用,execvp
... 等等。作为一个 C 语言和 Linux 经验有限的初学者,只有以下 explanation 似乎适合我:
It's executing ls
with 2 arguments: >
and awd.txt
. It is equivalent to running:
'ls' '>' 'awd.txt'
这是主题:What does execvp actually do?
但是,我向回答的人提出了以下问题,他没有回答,因此我不顾一切地单独询问,试图理解它。
所以要在execvp
中执行ls -a
,我们应该做execvp ("ls", args)
; args
在哪里 {"ls", "-a"}
?或 execvp (args[0], args)
?
谁能告诉我这是不是真的:execvp
从数组 args
中获取第一个参数,然后将其发送到内核以跟随以下数组参数?所以 execvp(args[0],args);
会是 args [] = {"ls", "-a"}
数组 args[0]
将 ls
发送到内核,然后呢?它会寻找另一个 args[0]
并找到-a
并发送,内核确定这两个命令像 ls -a
?
原型为:
int execvp(const char *file, char *const argv[]);
第一个参数,file
是要执行的程序的名称。 execvp
将搜索您的路径并尝试找到匹配项。来自联机帮助页:
The execlp(), execvp(), and execvpe() functions duplicate the
actions of the shell in searching for an executable file if the
specified file name does not contain a slash (/) character.
The file is sought in the colon-separated list of directory
pathnames specified in the PATH environment variable.
If/when execvp 找到一个匹配项,该程序将被加载到内存中并替换您当前的 运行 程序。
新程序将看到的参数是 execvp 中指定的 argv
数组。您应该将空指针作为最后一个元素,否则您的程序可能会因寻找空指针而崩溃。
如果你这样做:
char *argv[]={"bar","bash","penguin",0};
execvp("foo",argv);
那么当 foo 启动时,它会和你当前的程序有相同的环境,它的 argc 会是 3,它的 argv 会是上面的列表。即使程序名称是 "foo",它也是 argv[0] 而 运行 将显示为 "bar"。
您实际上不必将 argv[0] 作为新程序的名称。这是预期的,但不是必需的。
顺便说一句,以你的例子为例
ls > awd.txt
如果您在命令行上执行此操作,您的 shell 将分叉创建其自身的新副本。 child shell 将打开 awd.txt 并执行 dup2() 以将附加到 awd.txt 的 child fd 作为 1。经过一些其他整理后,child shell 会做类似的事情。
execvp("ls", {"ls", 0})
so 在创建的"ls" argc==1 和argv[1] ==0。传统上,我们会说 ls 有 0 个参数。
我在execvp
上找到了很多解释和答案,但看起来都很混乱。 execvp
获取命令并将其发送到内核然后执行某些操作,execvp
创建图像,execvp
是系统调用,execvp
... 等等。作为一个 C 语言和 Linux 经验有限的初学者,只有以下 explanation 似乎适合我:
It's executing
ls
with 2 arguments:>
andawd.txt
. It is equivalent to running:'ls' '>' 'awd.txt'
这是主题:What does execvp actually do?
但是,我向回答的人提出了以下问题,他没有回答,因此我不顾一切地单独询问,试图理解它。
所以要在execvp
中执行ls -a
,我们应该做execvp ("ls", args)
; args
在哪里 {"ls", "-a"}
?或 execvp (args[0], args)
?
谁能告诉我这是不是真的:execvp
从数组 args
中获取第一个参数,然后将其发送到内核以跟随以下数组参数?所以 execvp(args[0],args);
会是 args [] = {"ls", "-a"}
数组 args[0]
将 ls
发送到内核,然后呢?它会寻找另一个 args[0]
并找到-a
并发送,内核确定这两个命令像 ls -a
?
原型为:
int execvp(const char *file, char *const argv[]);
第一个参数,file
是要执行的程序的名称。 execvp
将搜索您的路径并尝试找到匹配项。来自联机帮助页:
The execlp(), execvp(), and execvpe() functions duplicate the actions of the shell in searching for an executable file if the specified file name does not contain a slash (/) character.
The file is sought in the colon-separated list of directory pathnames specified in the PATH environment variable.
If/when execvp 找到一个匹配项,该程序将被加载到内存中并替换您当前的 运行 程序。
新程序将看到的参数是 execvp 中指定的 argv
数组。您应该将空指针作为最后一个元素,否则您的程序可能会因寻找空指针而崩溃。
如果你这样做:
char *argv[]={"bar","bash","penguin",0};
execvp("foo",argv);
那么当 foo 启动时,它会和你当前的程序有相同的环境,它的 argc 会是 3,它的 argv 会是上面的列表。即使程序名称是 "foo",它也是 argv[0] 而 运行 将显示为 "bar"。
您实际上不必将 argv[0] 作为新程序的名称。这是预期的,但不是必需的。
顺便说一句,以你的例子为例
ls > awd.txt
如果您在命令行上执行此操作,您的 shell 将分叉创建其自身的新副本。 child shell 将打开 awd.txt 并执行 dup2() 以将附加到 awd.txt 的 child fd 作为 1。经过一些其他整理后,child shell 会做类似的事情。
execvp("ls", {"ls", 0})
so 在创建的"ls" argc==1 和argv[1] ==0。传统上,我们会说 ls 有 0 个参数。