我从目录中执行一个简单的shell程序执行的程序,我可以运行与我的shell可执行文件在同一文件夹中的文件,但无法运行诸如ls.exe之类的程序。的execve(......)不,尽管传递PATH变量
令牌容器在下列元素中包含文件名作为第一个元素和任何后续标记(例如输入“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变量的地图,但由于我甚至无法得到这个工作,我认为这将是毫无意义的,包括。
我编辑的帖子,包括我的功能的其余部分。 我只想澄清一下,如果execve()在加载新程序后没有使用传入的环境变量来设置进程的环境变量,那么什么是环境变量数组参数? – ozma
@ozma正如我所说的,它将环境传递给执行'exec'的* new *程序。如果你不知道,在POSIX系统(如Linux或macOS,其中'exec'是标准化的)中,'main'函数可以有一个* third *参数,通常命名为'env'并且被声明并且类似于' argv'数组。这是'execve'传递的环境(并且可以通过新程序中的'getenv'获得)。 –
哦,对!我一直认为自从传递环境变量以来,他们也会参与执行程序。这也是我第一次听说关于main的第三个参数。万分感谢。 – ozma