试图了解 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 个参数。