簡體   English   中英

execve 參數的路徑名與 arguments

[英]pathname vs arguments for execve parameters

我正在嘗試實現一個運行用戶輸入命令的簡單 shell 程序。 我希望用戶輸入“ls”或“dir”並讓 shell 運行 /bin/ls 或 /bin/dir。 對於 execve 參數,什么是正確的:

char *args[] ={"/bin/", "ls", NULL};
//Fork, pid, etc...then
execve(args[0], args+1, NULL);

還是會有所不同?? 我看到有些人使用/bin/ls作為路徑名,然后沒有 arguments 或ls作為路徑名和\bin作為環境? 我嘗試了上面的方法,但它沒有用,所以我想知道它是否是我發送的 arguments,或者我是否應該在我的代碼中的其他地方尋找問題。 請注意,我對 execve 的其他變體不感興趣,例如 execvp。 我在 Linux 系統上。 謝謝

路徑名

execve()中的路徑名必須是可執行文件的完整路徑,例如/bin/ls 如果使用execvpe() ,您可以單獨使用ls作為路徑名,但正如您已經指定的那樣,您不想使用它。

ARGUMENTS

arguments 應該是一個字符串數組,一個字符串對應命令行上指定的每個以空格分隔的參數。 最后一個應該是 NULL。第一個參數應該是路徑名本身。 例如:

char* args[] = {"/bin/ls", "-la", "foo/bar", NULL};

環境

使用execve()時不能省略環境變量。 某些實現中, NULL可以作為最后一個參數傳遞給execve() ,但這不是標准的。 相反,您應該傳遞一個指向 null 指針的指針; 本質上是一個空的環境變量數組。

把它放在一起

char *args[] ={"/bin/ls", "-foo", "bar", NULL};
//Fork, pid, etc...then
char* nullstr = NULL;
execve(args[0], args, &nullstr);

來自execve [強調添加]

 int execve(const char *pathname, char *const argv[], char *const envp[]);

execve() 執行路徑名引用的程序。 這導致調用進程當前正在運行的程序被新程序替換,具有新初始化的堆棧、堆和(已初始化和未初始化的)數據段。

路徑名必須是二進制可執行文件或以以下形式的行開頭的腳本:

   #!interpreter [optional-arg]

有關后一種情況的詳細信息,請參閱下面的“解釋器腳本”。

argv 是一個指針數組,指向作為命令行 arguments 傳遞給新程序的字符串。按照慣例,這些字符串中的第一個(即 argv[0])應該包含與正在執行的文件關聯的文件名。 argv 數組必須以 NULL 指針結尾。 (因此,在新程序中,argv[argc] 將為 NULL。)

在您的情況下, pathname應該是"/bin/ls"而不是"/bin/" 如果你想通過命令傳遞任何命令行參數,你可以為第一個參數提供argv向量索引1 ,第二個參數索引2等等,並用NULL終止參數向量。

一個用/bin/ls程序替換當前可執行映像並運行/bin/ls testfile的示例程序:

#include <stdio.h>
#include <unistd.h>

int main (void) {
    char *args[] = {"/bin/ls", "testfile", NULL};
    // here you can call fork and then call execve in child process
    execve(args[0], args, NULL);

    return 0;
}

Output:

# ./a.out 
testfile

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM