execve(..) 不执行程序,尽管传入了 PATH 变量

execve(...) does not execute program despite passing in PATH variable

本文关键字:PATH 变量 执行程序 execve      更新时间:2023-10-16

我正在从目录中执行一个简单的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 变量映射,但由于我什至无法让它工作,我认为包含它是没有意义的。

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

有了这些知识,就很容易找到适合您的解决方案,以及如何使用execvp(您需要使用,execve并没有真正使用您传递的环境,它只是将其传递给新程序): 您fork并使用setenv来设置流程的PATH, 在打电话之前execvp.