The execve()
函数不查看 PATH;为此,你需要execvp()
。您的程序无法执行ls
,显然你不会报告执行程序失败后execve()
。请注意,成员exec*()
函数族仅在出错时返回。
如果您运行该程序,您会得到您期望的结果(或多或少)/bin
作为您当前的目录(因为./ls
- aka ls
- 然后就会存在)。
您需要在第一个参数中提供可执行文件的路径名execve()
,使用适当的 PATH 设置找到它后。
或者继续使用execvp()
,但设置变量environ
到你的新环境。注意environ
在 POSIX 全局变量中是独一无二的,因为它没有在任何标头中声明。
extern char **environ;
environ = env_args;
execvp(args[0], &args[0]);
您不需要保存旧值并恢复它;您处于子进程中,切换其环境不会影响主程序(shell)。
这似乎按照我的预期工作 - 并证明原始代码的行为符合我的预期。
#include <stdio.h>
#include <unistd.h>
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;
}
我听到“哎呀!”接下来是我的目录列表。当我创建可执行文件时ls
在我当前的目录中:
#!/bin/sh
echo "Haha!"
然后我就听不到“哎呀!”并得到“哈哈!”。