Linux系統編程——進程替換:exec 函數族,linuxexec

來源:互聯網
上載者:User

Linux系統編程——進程替換:exec 函數族,linuxexec

在 Windows 平台下,我們可以通過雙擊運行可執行程式,讓這個可執行程式成為一個進程;而在 Linux 平台,我們可以通過 ./ 運行,讓一個可執行程式成為一個進程。


但是,如果我們本來就運行著一個程式(進程),我們如何在這個進程內部啟動一個外部程式,由核心將這個外部程式讀入記憶體,使其執行起來成為一個進程呢?這裡我們通過 exec 函數族實現。


exec 函數族,顧名思義,就是一簇函數,在 Linux 中,並不存在 exec() 函數,exec 指的是一組函數,一共有 6 個:

#include <unistd.h>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[]);

其中只有 execve() 是真正意義上的系統調用,其它都是在此基礎上經過封裝的庫函數。


exec 函數族提供了六種在進程中啟動另一個程式的方法。exec 函數族的作用是根據指定的檔案名稱或目錄名找到可執行檔,並用它來取代調用進程的內容,換句話說,就是在調用進程內部執行一個可執行檔。


進程調用一種 exec 函數時,該進程完全由新程式替換,而新程式則從其 main 函數開始執行。因為調用 exec 並不建立新進程,所以前後的進程 ID (當然還有父進程號、進程組號、當前工作目錄……)並未改變。exec 只是用另一個新程式替換了當前進程的本文、資料、堆和棧段(進程替換)。


exec 函數族的 6 個函數看起來似乎很複雜,但實際上無論是作用還是用法都非常相似,只有很微小的差別。



l(list):參數地址清單,以null 指標結尾。

v(vector):存有各參數地址的指標數組的地址。

p(path):按 PATH 環境變數指定的目錄搜尋可執行檔。

e(environment):存有環境變數字串地址的指標數組的地址。


exec 函數族裝入並運行可執行程式 path/file,並將參數 arg0 ( arg1, arg2, argv[], envp[] ) 傳遞給此程式。


exec 函數族與一般的函數不同,exec 函數族中的函數執行成功後不會返回,而且,exec 函數族下面的代碼執行不到。只有調用失敗了,它們才會返回 -1,失敗後從原程式的調用點接著往下執行。


execl() 範例程式碼:

#include <stdio.h>#include <unistd.h>int main(int argc, char *argv[]){printf("before exec\n\n");/* /bin/ls:外部程式,這裡是/bin目錄的 ls 可執行程式,必須帶上路徑(相對或絕對)   ls:沒有意義,如果需要給這個外部程式傳參,這裡必須要寫上字串,至於字串內容任意   -a,-l,-h:給外部程式 ls 傳的參數   NULL:這個必須寫上,代表給外部程式 ls 傳參結束*/execl("/bin/ls", "ls", "-a", "-l", "-h", NULL);// 如果 execl() 執行成功,下面執行不到,因為當前進程已經被執行的 ls 替換了perror("execl");printf("after exec\n\n");return 0;}


運行結果如下:



execv()範例程式碼:

execv() 和 execl() 的用法基本是一樣的,無非將列表傳參,改為用指標數組。


#include <stdio.h>#include <unistd.h>int main(int argc, char *argv[]){// execv() 和 execl() 的用法基本是一樣的,無非將列表傳參,改為用指標數組// execl("/bin/ls", "ls", "-a", "-l", "-h", NULL);/* 指標數組   ls:沒有意義,如果需要給這個外部程式傳參,這裡必須要寫上字串,至於字串內容任意   -a,-l,-h:給外部程式 ls 傳的參數   NULL:這個必須寫上,代表給外部程式 ls 傳參結束*/char *arg[]={"ls", "-a", "-l", "-h", NULL};// /bin/ls:外部程式,這裡是/bin目錄的 ls 可執行程式,必須帶上路徑(相對或絕對)// arg: 上面定義的指標數組地址execv("/bin/ls", arg);perror("execv");return 0;}

execlp() 或 execvp() 範例程式碼:

execlp() 和 execl() 的區別在於,execlp() 指定的可執行程式可以不帶路徑名,如果不帶路徑名的話,會在環境變數 PATH指定的目錄裡尋找這個可執行程式,而 execl() 指定的可執行程式,必須帶上路徑名。


#include <stdio.h>#include <unistd.h>int main(int argc, char *argv[]){// 第一個參數 "ls",沒有帶路徑名,在環境變數 PATH 裡尋找這個可執行程式// 其它參數用法和 execl() 一樣execlp("ls", "ls", "-a", "-l", "-h", NULL);/*char *arg[]={"ls", "-a", "-l", "-h", NULL};execvp("ls", arg);*/perror("execlp");return 0;}

execle() 或 execve() 範例程式碼:

execle() 和 execve() 改變的是 exec 啟動的程式的環境變數(只會改變進程的環境變數,不會影響系統的環境變數),其他四個函數啟動的程式則使用預設系統內容變數。


execle()範例程式碼:

#include <stdio.h>#include <unistd.h>#include <stdlib.h> // getenv()int main(int argc, char *argv[]){// getenv() 擷取指定環境變數的值printf("before exec:USER=%s, HOME=%s\n", getenv("USER"), getenv("HOME"));// 指標資料char *env[]={"USER=MIKE", "HOME=/tmp", NULL};/* ./mike:外部程式,當前路徑的 mike 程式,通過 gcc mike.c -o mike 編譯mike:這裡沒有意義NULL:給 mike 程式傳參結束env:改變 mike 程式的環境變數,正確來說,讓 mike 程式只保留 env 的環境變數 */execle("./mike", "mike", NULL, env);/*char *arg[]={"mike", NULL};execve("./mike", arg, env);*/perror("execle");return 0;}

外部程式,mike.c 範例程式碼:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(int argc, char *argv[]){printf("\nin the mike fun, after exec: \n");printf("USER=%s\n", getenv("USER"));printf("HOME=%s\n", getenv("HOME"));return 0;}

運行結果如下:



本教程範例程式碼下載請點此處。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.