Shell
/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
我在這裡做錯了什麼?
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);