【问题标题】:Why does my execve() only works when arguments include /bin/?为什么我的 execve() 仅在参数包含 /bin/ 时才有效?
【发布时间】:2020-06-02 19:04:05
【问题描述】:

execve() 仅在 /bin/ 是第一个参数的前缀时有效

例如./test.out ls./test.out /bin/ls 工作时什么也没找到

execve(argv[1], args, getenv("PATH"))

【问题讨论】:

  • 我想你在找execvpe()
  • 你有一个名为ls的文件吗?
  • 关于我之前的评论,请注意 execvpe 是 GNU 扩展,不是由 POSIX 定义的。我不确定它是使用当前环境中的PATH还是参数指定环境中的PATH

标签: c linux shell environment-variables


【解决方案1】:

execve() 不会在 PATH 中搜索可执行文件。您必须为此使用execvp()。名称中的p 代表PATH

【讨论】:

  • 或者execvpe,如果你也想设置环境的话。
  • @user253751 是的,但我认为 OP 认为传递 PATH 是获得这种行为的方法,这不是他真正需要的。
  • 我不确定 OP 是否认为通过 PATH 是可行的方法,或者他们只是想剥离环境。
  • 好吧,因为 execvpe 不是 POSIX,我不会推荐它。 cmets 已经足够好了。
【解决方案2】:

execve 不搜索 PATH 目录。第一个参数需要引用从当前目录可以访问的实际文件,所以如果文件不在当前目录中,则需要包含/字符。

Linux 支持 execvpe 作为 GNU 扩展,它是 execveexecvp POSIX 函数的交叉。 p 表示只要不包含 / 字符,它将在 PATH 中搜索文件。 (如果确实包含/ 字符,则与非p 版本相同。)e 表示在第三个参数中将新环境传递给函数。

OP 的代码将环境传递给 execve 函数,该函数仅包含来自原始环境的 PATH 环境变量。如果这是本意,则可以通过在调用execvp 之前剥离环境以符合 POSIX 的方式执行相同的效果。这利用了#include <unistd.h> 声明的extern char **environ; 变量:

char *env_p = getenv("PATH");
char *args[] = {argv[1], argv[2], NULL};

if (environ[0]) {
    environ[0] = env_p;
    environ[1] = NULL;
}

if (execvp(argv[1], args) < 0) {
    perror("execvp");
    exit(EXIT_FAILURE);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-26
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 2013-05-29
    • 2022-10-26
    • 2022-11-02
    • 1970-01-01
    相关资源
    最近更新 更多