linux进程---exec族函数(execl, execlp, execv, execvp, )解释和配合fork的使用
exec族函數函數的作用:
????????exec函數族的作用是根據指定的文件名找到可執行文件,并用它來取代調用進程的內容,換句話說,就是在調用進程內部執行一個可執行文件。這里的可執行文件既可以是二進制文件,也可以是任何Linux下可執行的腳本文件。
????????與一般情況不同,exec函數族的函數執行成功后不會返回,因為調用進程的實體,包括代碼段,數據段和堆棧等都已經被新的內容取代,只留下進程ID等一些表面上的信息仍保持原樣,頗有些神似"三十六計"中的"金蟬脫殼"。看上去還是舊的軀殼,卻已經注入了新的靈魂。只有調用失敗了,它們才會返回一個-1,從原程序的調用點接著往下執行。
????????我們應該明白了,Linux下是如何執行新程序的,每當有進程認為自己不能為系統和用戶做出任何貢獻了,他就可以發揮最后一點余熱,調用任何一個exec,讓自己以新的面貌重生;或者,更普遍的情況是,如果一個進程想執行另一個程序,它就可以fork出一個新進程,然后調用任何一個exec,這樣看起來就好像通過執行應用程序而產生了一個新進程一樣。
函數族
????????exec函數族分別是:execl, execlp, execle, execv, execvp, execvpe 但是對于初學者來說先學習一下四個exec族函數。
返回值
????????如果執行成功則函數不會返回,執行失敗則直接返回-1,原程序接著從調用處執行,失敗原因存于errno 中。
函數原型
參數說明
path:可執行文件的路徑名字
arg:可執行程序所帶的參數,第一個參數為可執行文件名字,沒有帶路徑且arg必須以NULL結束
file:如果參數file中包含/,則就將其視為路徑名,否則就按 PATH環境變量,在它所指定的各目錄中搜尋可執行文件。
exec族函數參數極難記憶和分辨,函數名中的字符會給我們一些幫助:
l : 使用參數列表
p:使用文件名,并從PATH環境進行尋找可執行文件
v:應先構造一個指向各參數的指針數組,然后將該數組的地址作為這些函數的參數。
e:多了envp[]數組,使用新的環境變量代替調用進程的環境變量
execl函數
int execl(const char *path, const char *arg, ...); #include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("before execl \n");if(execl("./exec","echoarg","abc",NULL)==-1)//要求exec結尾必須是NULL//echoarg是argv[0],abc是argv[1] // ./exec是可執行程序的路徑名{printf("execl failed \n");perror("why");//用來打印錯誤}printf("after execl\n");return 0; }execl實現ls指令
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("before execl \n");if(execl("/bin/ls","ls",NULL,NULL)==-1){printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execl實現 ls -l 指令
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("before execl \n");if(execl("/bin/ls","ls","-l",NULL)==-1)//這要在ls后給ls傳參-l即可{printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execl 獲取系統時間
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("this pro get system date: \n");if(execl("/bin/date","date",NULL,NULL)==-1){printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execlp函數
int execlp(const char *file, const char *arg, ...);file:如果參數file中包含/,則就將其視為路徑名,否則就按 PATH環境變量,在它所指定的各目錄中搜尋可執行文件
獲取系統時間代碼
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("this pro get system date: \n");if(execlp("date","date",NULL,NULL)==-1)//第一個參數不含/所以按 PATH環境變量,在它所指定的各目錄中搜尋可執行文件{printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execvp函數
int execvp(const char *file, char *const argv[]); //其實就是將execlp函數的后三個參數 //寫入創建已好的數組指針代碼演示
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("this pro get system date: \n");char*argv[]={"data",NULL,NULL};if(execvp("date",argv)==-1)printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execv函數
int execv(const char *path, char *const argv[]); //其實就是將execl函數的后三個參數 //寫入創建已好的數組指針代碼演示
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("this pro get system date: \n");char*argv[]={"data",NULL,NULL};if(execv("/bin/date",argv)==-1){printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }exec配合fork使用代碼示例
#include<stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> int main() {pid_t fpid;int data;while(1){printf("please input a data\n");scanf("%d",&data);if(data==1){fpid=fork();if(fpid>0){wait(NULL);}if(fpid==0){execl("./changedata","changedata","config.txt",NULL);}}else{printf("do nothing\n");}}return 0; } //調用在子進程中調用exec去執行修改文件中的數值以下代碼和上面的代碼效果相同
#include<stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> int main() {pid_t fpid;int data;while(1){printf("please input a data\n");scanf("%d",&data);if(data==1){fpid=fork();if(fpid>0){wait(NULL);}if(fpid==0){int fdSrc;char* readbuf=NULL;fdSrc=open("config.txt",O_RDWR);int size=lseek(fdSrc,0,SEEK_END);readbuf=(char *)malloc(sizeof(char)*size+8);lseek(fdSrc,0,SEEK_SET);int n_read=read(fdSrc,readbuf,size);char *p=strstr(readbuf,"LENG=");if(p==NULL){printf("find fail\n");exit(-1);}p=p+strlen("LENG=");*p='5';lseek(fdSrc,0,SEEK_SET);int n_write=write(fdSrc,readbuf,strlen(readbuf));close(fdSrc);}}else{printf("do nothing\n");}}return 0; }總結
以上是生活随笔為你收集整理的linux进程---exec族函数(execl, execlp, execv, execvp, )解释和配合fork的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 冰点文库下载器绿色版V3.2.15(09
- 下一篇: linux 信号和信号量编程