【问题标题】:Trying to understand how execvp works试图了解 execvp 的工作原理
【发布时间】:2016-07-18 23:49:29
【问题描述】:

我在execvp 上找到了很多解释和答案,但这一切似乎都令人困惑。 execvp 接受一个命令并将其发送到内核然后执行一些操作,execvp 创建一个映像,execvp 是系统调用,execvp ...等等。作为一个 C 语言和 Linux 经验有限的初学者,似乎只有以下explanation 为我点击:

它使用 2 个参数执行 ls:> 和 awd.txt。相当于运行:

'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的命令?

【问题讨论】:

  • 要执行ls -a,你需要:char *args[] = { "ls", "-a", 0 };,其中尾随空指针(写成0——如果你愿意,可以是NULL)是至关重要的。它标志着参数列表的结束,就像在main() 程序中的argv 中一样。假设给定的名称很简单(没有斜杠),它所做的是查找在PATH 环境变量中命名的目录,并将目录与可执行文件名称连接起来并尝试execv(pathname, args)。如果成功了,就没有机会了;如果失败,它会尝试PATH 上的下一个目录,直到成功或没有任何剩余。

标签: c unix execvp


【解决方案1】:

原型是:

  int execvp(const char *file, char *const argv[]);

第一个参数file 是要执行的程序的名称。 execvp 将搜索您的路径并尝试找到匹配项。从手册页:

execlp()、execvp() 和 execvpe() 函数复制 shell 在搜索可执行文件时的动作,如果 指定的文件名不包含斜杠 (/) 字符。
在以冒号分隔的目录列表中查找文件 在 PATH 环境变量中指定的路径名​​。

如果/当 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 将创建一个自己的新副本。子 shell 将打开 awd.txt 并执行 dup2() 以将附加到 awd.txt 的子 fd 设置为 1。经过其他一些内务处理后,子 shell 会执行类似的操作。

execvp("ls", {"ls", 0})

所以在创建的“ls”中,argc==1 和 argv[1] ==0。传统上,我们会说 ls 有 0 个参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多