【问题标题】:execve(...) does not execute program despite passing in PATH variable尽管传入 PATH 变量,execve(...) 不执行程序
【发布时间】:2017-10-20 18:30:04
【问题描述】:

我正在从目录中执行一个简单的 shell 程序:

/home/user/shell.exe

使用下面的代码,我可以运行与我的 shell 可执行文件位于同一文件夹中的文件,但无法运行 ls.exe 等程序。

标记容器包括文件名作为第一个元素和任何后续标记(例如输入“ls.exe -l”中的“-l”)在以下元素中。

if (fork())
{
  int status;
  wait(&status);
}
else
{
std::vector<const char*> exeArgs;
std::vector<const char*> envArgs;

std::for_each(tokens.begin(), tokens.end(),
[&exeArgs](const string& elem){ exeArgs.push_back(elem.c_str()); }
             );

exeArgs.push_back(nullptr);

string path = "PATH=";
path.append(getenv("PATH"));

envArgs.push_back(path.c_str());
envArgs.push_back(nullptr);

if (execve(exeArgs[0], const_cast<char *const *>(&exeArgs[0]),
                       const_cast<char *const *>(&envArgs[0])))
{
  std::cout << word << ": command not found" << std::endl;
  exit(0);
}
}

我已经花了无数个小时在谷歌上一遍又一遍地阅读手册页,但似乎不知道为什么这段代码不起作用。

我的想法是我的 shell 程序应该允许用户设置 PATH 变量,然后使用该 PATH 变量执行程序,这就是为什么我必须让 execve() 正常工作而不仅仅是使用 execvp()。

我在文件的单独部分中有一个 shell 变量映射,但由于我什至无法让它工作,我认为包含它是没有意义的。

【问题讨论】:

    标签: c++ shell exec execve


    【解决方案1】:

    是否知道exec 系列函数用新程序的图像替换当前进程?这就是为什么在exec 之前使用fork 如此普遍的原因。

    有了这些知识,很容易找到适合您的解决方案,以及您如何可以使用execvp(您需要使用它,execve 并没有真正使用您的环境通过,它只是将它传递给新程序):您fork并使用setenv设置new进程的PATH,然后调用execvp

    【讨论】:

    • 我编辑了帖子以包含我的其余功能。我想澄清一下,如果execve()在加载新程序后没有使用传入的环境变量来设置进程的环境变量,那么环境变量数组参数是干什么用的?
    • @ozma 正如我所说,它将环境传递给 new 程序,即exec 执行的程序。如果您不知道,在 POSIX 系统(如 Linux 或 macOS,exec 是标准化的)中,main 函数可以有一个 third 参数,通常命名为 env 并声明为与argv 数组类似。这是execve 传递的环境(将在新程序中通过getenv 提供)。
    • 哦,对了!一直以来,我都假设由于我传入了环境变量,它们也会在程序的执行中发挥作用。这也是我第一次听说 main 的第三个参数。非常感谢。
    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 2010-12-02
    相关资源
    最近更新 更多