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

Rob*_*131 3 command-line shell exec

我正在尝试运行一个简单的 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;
}
Run Code Online (Sandbox Code Playgroud)

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

/bin/sh: 0: Can't open sh
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么?

ilk*_*chu 11

char* argv[] = {"/bin/sh","sh","-c","/bin/ls", (char*) NULL};
execve(argv[0], argv, environ);
Run Code Online (Sandbox Code Playgroud)

请注意,您使用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
Run Code Online (Sandbox Code Playgroud)

这告诉 shell 尝试运行sh在当前目录中调用的脚本,如果脚本不存在,错误消息就是 Dash 给出的错误消息。零可能是命令行参数的行号。(Bash 给出了类似但不同的错误消息,并且似乎PATH也在寻找脚本。我不确定标准是否说明了关于PATH在此处使用的任何内容。)

你可以做

char *program = "/bin/sh";
char *argv[] = {"sh", "-c", "/bin/ls", NULL};
execve(program, argv, environ);
Run Code Online (Sandbox Code Playgroud)

或者可能

char *argv[] = {"/bin/sh", "sh", "-c", "/bin/ls", NULL};
execve(argv[0], argv + 1, environ);
Run Code Online (Sandbox Code Playgroud)

  • 呃,我想我昨晚说得有点太直率了,所以编辑了一点。@Robur_131,我希望你能解决问题。(并感谢 K 简单地说。) (2认同)