1. 程式人生 > >小何講程序:Linux中的exec函式族講解

小何講程序:Linux中的exec函式族講解

1.  exec函式族-exec()函式族說明
使用exec函式族主要有兩種情況
  • 當程序認為自己不能再為系統和使用者做出任何貢獻時,就可以呼叫exec函式族中的任意一個函式讓自己重生;
  • 如果一個程序想執行另一個程式,那麼它就可以呼叫fork()/vfork()函式新建一個程序,然後呼叫exec函式族中的任意一個函式,這樣看起來就像通過執行應用程式而產生了一個新程序(這種情況非常普遍)。 

2.  exec函式族-exec()函式族語法:


3.  exec函式族中的6個函式的區別 
     這6個函式在函式名和使用語法的規則上都有細微的區別,下面根據可執行檔案的查詢方式、引數表傳遞方式及環境變數傳遞這三個方面進行比較。

  • 查詢方式。
前4個函式的查詢方式都是根據完整的檔案目錄路徑和檔名查詢可執行檔案的。
而最後2個函式(也就是以p結尾的兩個函式)可以只給出可執行檔名,系統就會自動按照環境變數“$PATH”所指定的路徑進行查詢。
  • 引數傳遞方式。
exec函式族的引數傳遞有兩種方式:
一種是逐個列舉的方式(l)
另一種則是將所有引數整體構造指標陣列傳遞(v)。
在這裡是以函式名的第5位字母來區分的
字母為“l”(list)的表示逐個列舉引數的方式,其語法為char *arg;
字母為“v”(vector)的表示將所有引數整體構造字元指標陣列傳遞,其語法為*const argv[]。
觀察execl()、execle()、execlp()的語法與execv()、execve()、execvp()的區別。

注意:

引數實際上就是使用者在執行這個可執行檔案時所需的全部命令選項字串(包括該可執行程式名本身)。
引數必須以NULL表示結束,如果使用常數0表示一個空指標,則必須要把它強制轉化成一個字元指標((char *)0),否則exec將把它解釋為一個整型引數。
例如:執行cat命令連線顯示兩檔案內容
execl("/bin/cat","cat","/root/test1.c","/root/test2.c",NULL);
或者execlp("cat","cat","/root/test1.c","/root/test2.c",NULL);
char *argv[]={"cat","/root/test1.c","/root/test2.c",NULL};
execv("/bin/cat",argv);
或者:execvp("cat",argv);

  • 環境變數

exec函式族可以使用系統預設的環境變數,也可以傳入指定的環境變數(程序想要為將執行的程式指定一個確定的環境時)。
通過以“e”(environment)結尾的兩個函式execle()和execve()就可以在envp[]中指定當前程序所使用的環境變數。

  • 如何記憶這6個函式
這六個exec函式的引數很難記憶。函式名中的字元會給我們一些幫助:
字母 p表示可以只給出可執行檔名,系統會自動按照PATH環境變數所指定的路徑尋找可執行檔案,它與字母e互斥。
字母l表示該函式使用一個引數列表傳遞引數,它與字母v互斥。
v表示該函式使用一個char * argv[ ]傳遞引數。
最後,字母e表示該函式使用char * envp[ ] 傳遞環境量變,而不使用當前環境。


4.  exec使用例項:

/*  execlp.c  */

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
	int ret=0;
	if(fork()==0)
	{
		if((ret=execlp("ps","ps","-ef",NULL))<0)
		{
			printf("Execlp error! \n");
		}
	}	
	return 0;
}
執行截圖: