Linux系統程式設計之exec族函式

2021-10-03 09:46:54 字數 4622 閱讀 7770

目錄

一、說在前面

二、函式介紹

2.1、函式原型

2.2、函式功能

2.3、函式引數

2.3.1引數傳遞方式

2.3.2 區別與不同

2.4 函式關係

三、例項歷程

3.1 execl 示例:

3.2 execlp 示例:

3.3 execv 示例:

3.4 execvp 示例:

3.6 execve 示例:

3.7 其它示例:

四、總結

fork函式建立新的子程序後,子程序往往需要呼叫乙個 exec 函式來執行另外乙個程式。當程序呼叫一種 exec 函式時,該程序執行的程式完全替換為新程式,而新程式則從main函式開始執行。因為呼叫 exec 函式並不建立新的程序,所以前後的程序id並未改變。exec只是用磁碟上的乙個新程式替換了當前程序的正文段、資料段、堆段和棧段。

#include extern char **environ;

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

/* (char *) null */);

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

/* (char *) null */);

int execle(const char *path, const char *arg, ...

/*, (char *) null, 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);

#include int fexecve(int fd, char *const ar**, char *const envp);

exec 函式族的作用是執行第乙個引數指定的可執行程式。但其工作過程與 fork 完全不同, fork 是在複製乙份原程序,而 exec 函式執行第乙個引數指定的可執行程式之後,這個新程式執行起來後也是乙個程序,而這個程序會覆蓋原有程序空間,即原有程序的所有內容都被新執行起來的程序全部覆蓋了,所以 exec 函式後面的所有**都不再執行,但它之前的**當然是可以被執行的。

path 是包括執行檔名的全路徑名   file 既可是全路徑名也可是可執行檔名;

最後乙個取檔案描述符作為引數

arg 是可執行檔案的全部命令列引數,可以用多個,注意最後乙個引數必須為 null;

ar** 是乙個字串的陣列 char *ar**=;

envp 指定新程序的環境變數 char *envp=;

exec函式族的引數傳遞方式: 第一種是逐個列舉的方式;

第二種則是將所有引數整體構造指標陣列傳遞。

在這裡是以函式名的第 5 位字母來區分的:

1、字母為「l」(list)的表示逐個列舉的方式,其語法為 char *arg;

2、字母為「v」 (vertor)的表示將所有命令列引數整體構造指標陣列傳遞,其語法為 char *const ar**。

以字母 p 結尾的函式通過搜尋系統 path 這個環境變數來查詢新程式的可執行檔案的路徑。如果可執行程式不在 path 定義的路徑中,我們就需要把包括目錄在內的使用絕對路徑的檔名作為引數傳遞給函式。

以字母 e 結尾的函式通過傳遞 envp 傳遞字串陣列作為新程式的環境變數。新程序中的全域性變數 environ 指標指向的環境變數陣列將會被 envp 中的內容替代。

注意:對於有引數 envp 的函式,它會使用程式設計師自定義的環境變數,如果自定義的環境變數中包含了將要執行的可執行程式的路徑,那麼第乙個引數中是不是我們就可以不用寫全路徑了呢?不是的,必須寫全路徑。因為我們自定義的環境變數不是用來尋找這個可執行程式的,而是在這個可執行程式執行起來之後給新程序用的。

可以用 env 命令檢視環境變數。

(在上面的基礎上去掉了 ls 的路徑/bin/)

#include #include int main()

(把"ls","-l",null 這些命令列引數通過指標陣列 str 傳給 exec 函式)

#include #include int main()

; printf("aaaa\n");

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

printf("bbbb\n");

printf("bbbb\n");

return 0;

}

(在上面的基礎上去掉了 ls 的路徑/bin/)

#include #include int main()

; printf("aaaa\n");

execvp("ls", str);

printf("bbbb\n");

printf("bbbb\n");

return 0;

}

3.5execle 示例:

#include #include int main()

; printf("aaaa\n");

execle("/bin/ls", "ls", "-l", null, arrenv);

printf("bbbb\n");

printf("bbbb\n");

return 0;

}

#include #include int main()

; char *arrenv = ;

printf("aaaa\n");

execve("/bin/ls", str, arrenv);

printf("bbbb\n");

printf("bbbb\n");

return 0;

}

get_arg.c 測試 environ,用來輸出本程序預設的環境變數

#include #include #include extern char **environ; //宣告該變數

int main(int argc,char *ar**)

{ int i=0;

for(;iexec 函式族的作用是根據指定的檔名找到可執行檔案,並用它來取代呼叫程序的內容,換句話說,就是在呼叫程序內部執行乙個可執行檔案。這裡的可執行檔案既可以是二進位制檔案,也可以是任何 linux 下可執行的指令碼檔案,如果不是可以執行的檔案,那麼就解釋成為乙個 shell 檔案, sh **執行!

上面 7 條函式看起來似乎很複雜,但實際上無論是作用還是用法都非常相似,只有很微小的差別。

引數 argc 指出了執行該程式時命令列引數的個數,陣列 ar** 存放了所有的命令列引數,陣列 envp 存放了所有的環境變數。環境變數指的是一組值,從使用者登入後就一直存在,很多應用程式需要依靠它來確定系統的一些細節,我們最常見的環境變數是 path,它指出了應到**去搜尋應用程式,如 /bin; home 也是比較常見的環境變數,它指出了我們在系統中的個人目錄。環境變數一般以字串"***=***"的形式存在, *** 表示變數名, *** 表示變數的值。

值得一提的是, ar** 陣列和 envp 陣列存放的都是指向字串的指標,這兩個陣列都以乙個 null 元素表示陣列的結尾。

前 3 個函式都是以 execl 開頭的,後 3 個都是以 execv 開頭的,它們的區別在於, execv 開頭的函式是以"char

*ar**"這樣的形式傳遞命令列引數,而 execl 開頭的函式採用了我們更容易習慣的方式,把引數乙個乙個列出來,

然後以乙個 null 表示結束。這裡的 null 的作用和 ar** 陣列裡的 null 作用是一樣的。

這裡建議使用 (char *)0 代替 null。

在全部 7 個函式中,只有 execle、 execve 和 fexecve使用了 char *envp傳遞環境變數,其它的 4 個函式都沒有這個參

數,這並不意味著它們不傳遞環境變數,這 4 個函式將把預設的環境變數不做任何修改地傳給被執行的應用程式。而 execle 和 execve 和 fexecve會用指定的環境變數去替代預設的那些。

還有 2 個以 p 結尾的函式 execlp 和 execvp,咋看起來,它們和 execl 與 execv 的差別很小,事實也確是如此,除 execlp 和 execvp 之外的 4 個函式都要求,它們的第 1 個引數 path 必須是乙個完整的路徑,如"/bin/ls";而 execlp和 execvp 的第 1 個引數 file 可以簡單到僅僅是乙個檔名,如 "ls",這兩個函式可以自動到環境變數 path 制定的目錄裡去尋找。

linux系統程式設計之exec函式族

linux函式exec函式族 這來函式是用來執行一些可執行檔案的,常用在fork出子程序後,在子程序中執行。也就是替換子程序的東西,子程序的東西全部被替換,但只是替換,不會產生乙個新的程序,程序的id號也不會改變。include extern char environ int execl const...

linux系統程式設計 exec函式族

例項 include include include intmain void else if pid 1 else return0 hello.c 輸出自己pid和環境變數 include include extern char environ intmain void include inclu...

Linux系統程式設計 exec函式族

fork 建立子程序之後執行的是和父程序相同的程式 可能執行不同的 分支 子程序呼叫exec函式執行另一程式,該程序的使用者空間 和資料完全被新程式替換,從新程式的啟動例程開始執行。exec並不傳建立新程序,所以呼叫exec前後該程序的id並未改變。exec函式族 int execl const c...