linux系統程式設計-exec函式族
阿新 • • 發佈:2018-12-13
exec函式族
- fork建立子程序後執行的是和父程序相同的程式(但有可能執行不同的程式碼分支),子程序往往要呼叫一種exec函式以執行另一個程式。
- 當程序呼叫一種exec函式時,該程序的使用者空間程式碼和資料完全被新程式替換,從新程式的啟動例程開始執行。
- 呼叫exec並不建立新程序,所以呼叫exec前後該程序的id並未改變。
execlp函式
- int execlp(const char *file, const char *arg, …):載入一個程序,藉助PATH環境變數
- 引數1:要載入的程式的名字(該引數需要配合PATH環境變數來使用,當PATH中所有目錄搜尋後沒 有引數1則出錯返回)
- 引數 2、3…:argv[0]、argv[2]、…NULL(必須以NULL結尾)
- 該函式通常用來呼叫系統程式。如:ls、date、cp、cat等命令。
例項程式碼:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
pid = fork();
if(pid<0)
{
perror ("fork error");
exit(1);
}
else if(pid>1)
{
printf("i am parent");
sleep(1);
}
else
{
int tmp = execlp("ls","ls","-l","-a",NULL); //子程序執行 ls -al 命令
if (tmp<0)
exit(1);
}
return 0;
}
結果:執行app程式 和 執行 ls -al 命令結果一樣
execl函式
- int execl(const char *path, const char *arg, …):載入一個程序, 通過 路徑來載入。
- 對比execlp,如載入 “ls” 命令帶有-l,-F引數 execlp(“ls”, “ls”, “-l”, “-F”, NULL); 使用程式名在PATH中搜索。 execl("/bin/ls", “ls”, “-l”, “-F”, NULL); 使用引數1給出的絕對路徑搜尋。
execle函式
- int execle(const char *path, const char *arg, …, char *const envp[] ):使用路徑呼叫程式,使用新的環境變數陣列設定被呼叫的程式的環境變數
hello.c : 輸出自己pid和環境變數
#include <stdio.h>
#include <unistd.h>
extern char** environ;
int main(void)
{
printf("hello pid is:%d \n" ,getpid() );
int i;
for(i=0;environ[i];i++)
printf("%s\n",environ[i]);
return 0;
}
直接執行的結果: app.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
pid = fork();
if(pid<0)
{
perror("fork error");
exit(1);
}
else if(pid>1)
{
printf("i am parent\n");
sleep(1);
}
else
{
char* envp[]={"AA=BBCCDD",NULL};
int tmp = execle("./xx/hello","app1",NULL,envp); //hello 上面的程式
if(tmp<0)
{
exit(1);
printf("child dead");
}
}
return 0;
}
執行結果: hello 程序的 環境變數 變成 AA=BBCCDD
execv函式
- int execv(const char *path, char *const argv[]);
char* argv[]={"ls", "-l","-a","NULL"};
execv("/bin/ls",argv);
execvp函式
- int execvp(const char *file, char *const argv[]) :
char* argv[]={"ls", "-l","-a","NULL"};
execv("ls",argv);// ls藉助PATH環境變數
execve函式
- int execve(const char *path, char *const argv[], char *const envp[])
小結
- 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)
- path:傳遞的是可執行程式的路徑
- file:可執行程式名,依靠環境變數來找
- arg:傳遞 “argv[0]” ,“argv[1]”,…NULL
- argv[]: 定義一個字串指標陣列(命令列引數) 傳進去 :char* argv[]={“ls”, “-l”,"-a",“NULL”};:
- envp[]: 定義一個字串指標陣列(環境變數) 傳進去: char* envp[]={“AA=BBCCDD”,NULL};
(2)
- l (list) 命令列引數列表
- p (path) 搜素file時使用path變數
- v (vector) 使用命令列引數陣列
- e (environment) 使用環境變數陣列 ,不使用程序原有的環境變數,設定新載入程式執行的環境變數
(3)
- 事實上,只有execve是真正的系統呼叫,其它五個函式最終都呼叫execve,所以execve在man手冊第2節,其它函式在man手冊第3節。這些函式之間的關係如下圖所示。