Linux中exec族函式詳解

2021-09-07 22:53:16 字數 3183 閱讀 1053

(1)exec函式說明:

fork函式是用於建立乙個子程序,該子程序幾乎是父程序的副本,而有時我們希望子程序去執行另外的程式,exec函式族就提供了乙個在程序中啟動另乙個程式執行的方法。它可以根據指定的檔名或目錄名找到可執行檔案,並用它來取代原呼叫程序的資料段、**段和堆疊段,在執行完之後,原呼叫程序的內容除了程序號外,其他全部被新程式的內容替換了。另外,這裡的可執行檔案既可以是二進位制檔案,也可以是linux下任何可執行指令碼檔案。

在linux中使用exec函式族主要有以下兩種情況:

(2)exec函式族語法

在linux中並沒有exec()函式,而是由6個以exec開頭的函式,所以稱之為族。他們之間的語法有著細微的差別,下面是在man冊中檢視「man 3 execl 」庫函式,函式原型如下:

#include extern char **environ;

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg, ..., char * const envp);

int execv(const char *path, char *const ar**);

int execvp(const char *file, char *const ar**);

int execvpe(const char *file, char *const ar**, char *const envp);

為了方便記憶,可以通過對這6個函式進行對比記憶,方法如下:

execl()與execv()    這兩個函式是最基本的exec,都可以用來執行乙個程式,區別是傳參的格式不同。execl是把引數列表(本質上是多個字串,必須以null結尾)依次排列而成(l其實就是list的縮寫),execv是把引數列表事先放入乙個字串陣列中,再把這個字串陣列傳給execv函式。

execlp和execvp     這兩個函式在上面2個基礎上加了p,較上面2個來說,區別是:上面2個執行程式時必須指定可執行程式的全路徑(如果exec沒有找到path這個檔案則直接報錯),而加了p的傳遞的可以是file(也可以是path,只不過相容了file。加了p的這兩個函式會首先去找file,如果找到則執行執行,如果沒找到則會去環境變數path所指定的目錄下去找,如果找到則執行如果沒找到則報錯)

execle和execvpe   這兩個函式較execl()與execv()來說加了e (注意execvpe函式命名中並沒有將p去掉,原因後面有說明),函式的引數列表中也多了乙個字串陣列envp形參,e就是environment環境變數的意思,和基本版本的exec的區別就是:執行可執行程式時會多傳乙個環境變數的字串陣列給待執行的程式。如果使用者在執行這個程式時沒有傳遞第三個引數,則程式會自動從父程序繼承乙份環境變數(預設的,最早**於os中的環境變數);如果我們exec的時候使用execlp或者execvpe去給傳乙個envp陣列,則程式中的實際環境變數是我們傳遞的這乙份(取代了預設的從父程序繼承來的那乙份)

(3)函式使用例項

execl() 函式:

int main(void)

else if (pid == 0)

else

return 0;

}

注意:execl("/bin/ls", "ls", "-l", "-a", null);這條語句中的引數傳遞方式,第乙個引數是要執行的程式的絕對路徑,後面跟的「ls」這個引數,在實際測試中並沒有發現有什麼實際的用處(即使填寫的不是ls命令,是別的命令也沒有關係比如第二個引數是「pwd」,具體原因不解,望高手指教),但是這裡還必須填入乙個字串,這樣才可以正常進行命令的解析。

execv()函式

int main(void)

else if (pid == 0)

; execv("/bin/ls", arg);

return 0;

} else

return 0;

}

該函式以execl()的區別就是將命令以及字串賦值給乙個字串陣列,然後作為函式的引數傳入。其實本質是一樣的。

execlp()與execvp函式

int main(void)

else if (pid == 0)

; execvp("ls", arg);

return 0;

} else

return 0;

}

這兩個函式以前面的區別就是函式名不同,第乙個引數使用的是相對路徑。

execle()與execvpe()函式

int main(void)

else if (pid == 0)

; //自己定義的環境變數

/*execlp函式*/

execle("/bin/ls", "ls", "env", null, envp);

/*execvp函式*/

char *const arg = ;

execvpe("/bin/ls", arg, envp);

return 0;

} else

return 0;

}

實際上,真正的系統呼叫只有execve(),(這就是為什麼在execvpe這個系統呼叫中命名的時候沒有將"p"去掉的原因)函式原型如下,上面的函式都是庫函式,他們最終都會呼叫execve()這個系統呼叫

#include int execve(const char *filename, char *const ar**, char *const envp);
在使用exec函式族時,一定要加上錯誤判斷語句。exec很容易執行失敗,其中最常見的原因如下:

可見核心的開發人員想的多麼的細緻,將一下使用者常見的錯誤都能想得到。

補充:關於main函式的傳參。

main函式的原型其實不止是int main(int argc, char **ar**) 或者nt main(int argc, char *ar**[ ])

還可以是 int main(int argc, char **ar**, char **env)  第三個引數是乙個字串陣列,內容是環境變數。

Linux中的exec函式族

fork 建立子程序後執行的是和父程序相同的程式 但有可能執行不同的 分支 子程序往往要呼叫一種 exec 函式以執行另乙個程式。當程序呼叫一種 exec 函式時,該程序的使用者空間 和資料完全被新程式替換,從新程式的啟動例程開始執行。呼叫 exec 並不建立新程序,所以呼叫 exec 前後該程序的...

Linux 程序 exec函式族

其他exec 函式 練習拓展dup2 dup to 函式 一 exec的簡介 1.fork建立程序後執行的是和父程序相同的程式 但有可能執行不同的 分支 子程序往往要呼叫一種exec函式執行另一種程式。當程序呼叫一種exec函式時,該程序的使用者空間 和資料完全被新程式替換,從新程式的啟動例程開始執...

Linux程序 exec族函式

1 為什麼要使用exec族函式 當我們fork乙個子程序就是為了執行乙個新的程式,此時可以呼叫exec族函式,執行已經編譯好的可執行程式或者linux自帶的ls cd等命令。2 exec族函式如何使用 函式原型 include extern char environ intexecl const c...