使用execve的新路径运行ls命令

我试图使用execve来运行ls命令。 目前我正在使用以下参数运行它:

execve(args[0], args, env_args) //args looks like {"ls", "-l", "-a", NULL} //env_args looks like {"PATH=/bin", "USER=me", NULL} 

我期望这样做是使用我的新env_args运行ls命令,这意味着它将在我的PATH中查找ls。 但是,这段代码实际上没有做任何事情,当我运行代码时它只返回我的命令提示符而没有输出。

使用相同的args []我使用execvp并且工作并搜索我当前的路径。

你能告诉我我做错了什么吗?

我想要做的是编写我自己的shell程序,在那里我可以创建和导出我自己的环境,并让exec使用我在char **中定义的环境。 本质上我正在编写自己的函数来操作env_args来添加和删除变量,当我调用exec时我希望能够在{“ls”,“ – l”,NULL}上调用exec并让它看不起我的新环境名为ls的有效程序的路径变量。 我希望这能解释我做得更好。 在这种情况下,我不认为extern environ var对我有用。

execve()不看PATH; 为此,你需要execvp() 。 你的程序没有执行ls ,显然你没有报告在execve()之后执行程序的失败。 请注意, exec*()系列函数的成员仅在出错时返回。

如果您使用/bin作为当前目录运行程序(因为./ls – aka ls – 将存在),您将得到预期的结果(或多或少)。

在使用适当的PATH设置查找后,您需要在execve()的第一个参数中提供可执行文件的路径名。

或继续使用execvp() ,但将变量environ设置为新环境。 请注意, environ现在(POSIX 2008)在声明,但以前未在任何地方声明。

 extern char **environ; environ = env_args; execvp(args[0], &args[0]); 

您不需要保存旧值并将其恢复; 你在子进程中并且切换它的环境不会影响主程序(shell)。


这看起来像我期望的那样 – 并且certificate了原始代码的行为和我期望的一样。

 #include  #include  extern char **environ; int main(void) { char *args[] = { "ls", "-l", "-a", NULL }; char *env_args[] = { "PATH=/bin", "USER=me", NULL }; execve(args[0], args, env_args); fprintf(stderr, "Oops!\n"); environ = env_args; execvp(args[0], &args[0]); fprintf(stderr, "Oops again!\n"); return -1; } 

我得到’哎呀!’ 然后列出我的目录。 当我在当前目录中创建一个可执行文件时:

 #!/bin/sh echo "Haha!" 

然后我没有得到’糟糕!’ 并得到’哈哈!’。