Shell

/bin/sh: 0: 無法打開 sh

  • July 20, 2019

我正在嘗試執行一個簡單的 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

我在這裡做錯了什麼?

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,,。這與呼叫幾乎相同。或者在 shell 命令行中:-c``/bin/ls``execl("/bin/sh", "/bin/sh", "sh", "-c", "/bin/ls", (char*) NULL)

$ /bin/sh sh -c /bin/ls
/bin/sh: 0: Can't open sh

這告訴外殼程序嘗試執行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);

引用自:https://unix.stackexchange.com/questions/531064