2017-10-20 56 views
0

我从目录中执行一个简单的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变量的地图,但由于我甚至无法得到这个工作,我认为这将是毫无意义的,包括。

回答

2

知道exec家庭的功能取代当前进程与新节目的图像?这就是为什么在exec之前使用fork这么常见。

武装与知识,很容易找到一个解决方案适合你,你怎么可以使用execvp(你需要使用,execve并没有真正使用你传递的环境,它只是将它传递给新程序):在调用execvp之前,您使用fork并使用setenv来设置PATH新的过程。

+0

我编辑的帖子,包括我的功能的其余部分。 我只想澄清一下,如果execve()在加载新程序后没有使用传入的环境变量来设置进程的环境变量,那么什么是环境变量数组参数? – ozma

+1

@ozma正如我所说的,它将环境传递给执行'exec'的* new *程序。如果你不知道,在POSIX系统(如Linux或macOS,其中'exec'是标准化的)中,'main'函数可以有一个* third *参数,通常命名为'env'并且被声明并且类似于' argv'数组。这是'execve'传递的环境(并且可以通过新程序中的'getenv'获得)。 –

+0

哦,对!我一直认为自从传递环境变量以来,他们也会参与执行程序。这也是我第一次听说关于main的第三个参数。万分感谢。 – ozma