/bin/sh: 0: 无法打开 sh

/bin/sh: 0: 无法打开 sh

我正在尝试运行一个简单的 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;
}

注释掉的 execl 运行良好。但是当我尝试对 execve 执行相同操作时,编译器会调用以下错误:

/bin/sh: 0: Can't open sh

我在这里做错了什么?

答案1

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 会给出错误消息。零可能是命令行参数的行号。 (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);

相关内容