Linux程序 exec函式操作

2021-07-09 21:42:13 字數 3257 閱讀 3462

fork建立子程序後執行的是和父程序相同的程式(但有可能執行不同的**分支),子程序往往要呼叫一種exec函式以執行另乙個程式。

當程序呼叫一種exec函式時,該程序的使用者空間**和資料完全被新程式替換,從新程式的啟動例程開始執行。

呼叫exec並不建立新程序,所以呼叫exec前後該程序的id並未改變。

以exec開頭的函式,統稱exec函式:

#include 

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 argv);

int execvp(const

char *file, char *const argv);

int execve(const

char *path, char *const argv, char *const envp);

這些函式如果呼叫成功則載入新的程式從啟動**開始執行,不再返回,如果呼叫出錯則返回-1,所以exec函式只有出錯的返回值而沒有成功的返回值。exec族函式各函式分析及記憶:不帶字母p(表示path)的exec函式第乙個引數必須是程式的相對路徑或絕對路徑,例如「/bin/ls」或「./a.out」,而不能是「ls」或「a.out」。

對於帶字母p的函式:

如果引數中包含/,則將其視為路徑名。

否則視為不帶路徑的程式名,在path環境變數的目錄列表中搜尋這個程式。

帶有字母l(表示list)的exec函式要求將新程式的每個命令列引數都當作乙個引數傳給它,命令列引數的個數是可變的,因此函式原型中有中的最後乙個可變引數應該是null,起sentinel(哨兵)的作用。

對於帶有字母v(表示vector)的函式,則應該先構造乙個指向各引數的指標陣列,然後將該陣列的首位址當作引數傳給它,陣列中的最後乙個指標也應該是null,就像main函式的argv引數或者環境變數表一樣。

對於e(表示environment)結尾的exec函式,可以把乙份新的環境變數表傳給它,其他exec函式仍使用當前的環境變數表執行新程式。

exec呼叫舉例如下:

char *const ps_argv =;

char *const ps_envp =;

execl("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", null);

execv("/bin/ps", ps_argv);

execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", null, ps_envp);

execve("/bin/ps", ps_argv, ps_envp);

execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", null);

execvp("ps", ps_argv);

事實上,只有execve是真正的系統呼叫,其它五個函式最終都呼叫execve,這些函式之間的關係如下圖所示:

乙個完整的例子:

#include 

#include

int main(void)

由於exec函式只有錯誤返回值,只要返回了一定是出錯了,所以不需要判斷它的返回值,直接在後面呼叫perror即可。注意在呼叫execlp時傳了兩個「ps」引數,第乙個「ps」是程式名,execlp函式要在path環境變數中找到這個程式並執行它,而第二個「ps」是第乙個命令列引數,execlp函式並不關心它的值,只是簡單地把它傳給ps程式,ps程式可以通過main函式的argv[0]取到這個引數。

實現i/o重定向

呼叫exec後,原來開啟的檔案描述符仍然是開啟的。利用這一點可以實現i/o重定向。

先看乙個簡單的例子,把標準輸入轉成大寫然後列印到標準輸出:

例大小寫轉換原始碼upper.c

/* upper.c */

#include

int main(void)

return

0;}

#include

#include

#include

#include

int main(int argc, char *argv)

fd = open(argv[1], o_rdonly);

if(fd<0)

dup2(fd, stdin_fileno);

close(fd);

execl("./upper", "upper", null);

perror("exec ./upper");

exit(1);}

學習資料來自邢文鵬老師

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...

Linux程序之exec族函式

fork函式建立新程序後,經常會在新程序中呼叫exec函式去執行另外乙個程式。當程序呼叫exec函式時,該程序被完全替換為新程式。因為呼叫exec函式並不建立新程序,所以前後程序的id並沒有改變。原創鏈結 include include include 函式原型 int execl const ch...