我试着运行一个简单的C程序。
#include <stdio.h>
#include <unistd.h>
extern char** environ;
int main(){
// execl("/bin/sh","sh","-c","/bin/ls -l",(char *) NULL);
char* argv[] = {"/bin/sh","sh","-c","/bin/ls", (char*) NULL};
execve(argv[0], argv, environ);
return 0;
}
注释掉的执行部分运行良好。但是,当我试图对execve执行同样的操作时,编译器将调用以下错误:
/bin/sh: 0: Can't open sh
我在这里做错什么了?
发布于 2019-07-19 18:34:40
char* argv[] = {"/bin/sh","sh","-c","/bin/ls", (char*) NULL};
execve(argv[0], argv, environ);
请注意,您使用了argv[0]
(/bin/sh
)两次,一次是作为execve()
的第一个参数,另一次是作为数组的一部分传递给它的第二个参数。这不是在execl()
调用中发生的情况,只有/bin/sh
作为第一个参数(程序文件)。
因此,您的execve()
执行文件/bin/sh
,给它/bin/sh
的程序名(零参数),以及常规参数sh
、-c
、/bin/ls
。这与调用execl("/bin/sh", "/bin/sh", "sh", "-c", "/bin/ls", (char*) NULL)
非常相似。或者在shell命令行中:
$ /bin/sh sh -c /bin/ls
/bin/sh: 0: Can't open sh
这告诉shell在当前目录中运行一个名为sh
的脚本,如果这个脚本不存在,错误消息就是Dash给出的。0可能是命令行参数的行号。(Bash提供了类似但不同的错误消息,并且似乎也从PATH
中寻找脚本。我不确定标准中是否有关于在这里使用PATH
的内容。
你可以代替
char *program = "/bin/sh";
char *argv[] = {"sh", "-c", "/bin/ls", NULL};
execve(program, argv, environ);
或者也许
char *argv[] = {"/bin/sh", "sh", "-c", "/bin/ls", NULL};
execve(argv[0], argv + 1, environ);
https://unix.stackexchange.com/questions/531064
复制相似问题