我對系統呼叫 execve 的使用感到困惑。第二個引數應該是指向引數的指標,但它不起作用,但是當我將整個命令(/bin/bash) arg 作為第二個引數發送時,它確實可以正確執行。
./test /bin/bash "echo 'this is a test' | wc -c"
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char *argv[]) {
execve(argv[1], &argv[1], NULL); ////works, but I dont understand how since the 2nd param is wrong.
return 0;
}
int main(int argc, char *argv[]) {
execve(argv[1], &argv[2], NULL); ////doenst work, it should since Im sending the correct aguments.
printf("hi");
return 0;
}
uj5u.com熱心網友回復:
argv[0]包含正在執行的檔案的名稱。因此,execve還需要將正在執行的檔案作為第一個元素(索引 0)。
uj5u.com熱心網友回復:
從execve(2)手冊頁:
argv是一個指向作為命令列引數傳遞給新程式的字串的指標陣列。按照慣例,這些字串中的第一個(即argv[0])應該包含與正在執行的檔案關聯的檔案名。argv陣列必須由指標NULL終止。(因此,在新程式中,argv[argc]將是NULL。)
換句話說,您在第二個引數中傳遞的引數串列包括可執行檔案本身的名稱(即使已在第一個引數中指定)。這就是可執行檔案如何能夠檢測它們是如何被呼叫的(例如通過符號鏈接)并在它們的“幫助”輸出中顯示正確的名稱。
uj5u.com熱心網友回復:
在 execve man 中我們可以看到它的原型是:
int execve(const char *pathname, char *const argv[], char *const envp[]);
根據 execve man ( https://man7.org/linux/man-pages/man2/execve.2.html )
argv 是一個指向作為命令列引數傳遞給新程式的字串的指標陣列。按照慣例,這些字串中的第一個(即 argv[0])應該包含與正在執行的檔案關聯的檔案名。argv 陣列必須由NULL 指標終止。(因此,在新程式中,argv[argc] 將為 NULL。)
關于這些規則,您的代碼應該是:
#include <stdio.h>
#include <unistd.h>
int main ()
{
char *filepath = "/bin/echo";
char *argv[] = { filepath, "Hello World", NULL };
execve (filepath, argv, NULL);
return 0;
}
uj5u.com熱心網友回復:
execvecall 執行來自呼叫者的程式。就像 C 中的任何程式一樣,它需要argv[0]設定為正在執行的可執行檔案的名稱。這通常在從命令列執行時自動完成,但由于您正在使用execve您必須自己完成。
如果argv_1[1] = <executable path for program_2>,當您從 program_1 呼叫 program_2 時execve(argv_1[1], &argv_1[1], NULL),program_2 收到一個 argv 陣列,如argv_2[0] = argv_1[1], argv_2[1] = argv_1[2],依此類推。
請注意您的第二個主要內容如何不遵循此規則。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/486395.html
