#include <unsitd.h> int execl( const char *pathname, const char *arg 0, ... /* (char *) 0 */); int execv( const char *pathname, const char *rgv[] ); int execle(const char *pathname,const char *arg 0, /* (char *)0, char *cones nt v p [] */); int execve(const char *pathname,const char *rgv[], char *consten vp [] ); int execlp(const char *filename,const char *arg 0, ... /* (char *) 0 */); int execvp(const char *filename,const char *rgv[] );
|
exec函数族一共是六个函数,在调用外部的可执行程序或者调用外部的脚本的时候就可以用到它,调用外部程序和脚本时,给程序或脚本需要开辟运行空间,所以在使用exec函数族前需要开辟新的进程以供外部程序或脚本运行,开启新的进程可以使用fork()和vfork()函数来完成,这两个函数都具有开启新进程的功能,但在使用上需要注意一些细节,如果用fork()开启新的进程,它会克隆和父进程一样的运行空间,而克隆会消耗一定的时间,会在效率上牺牲很多,而使用vfork(),它不会克隆父进程的信息,在未使用exec前,会和父进程共享数据,所以在使用vfork()开启新的进城后,最好不要进行写操作,否则带来的错误是很难调试的,在使用fork()或者vfork()开启新的进程后就可以是用exec函数族来调用外部的函数或者脚本文件了,下来对exec函数族加以详细的说明:
首先,对函数进行一些说明,理解exec函数的参数需要从main函数的参数开始,因为外部函数就是一个main函数,linux推荐的main函数的定义应该为:
int main(int argc,char *argv[],char *env[]); // int argc 代表输入参数的个数 //char *argv 代表输入参数的字符串首地址 argv[0]存储可执行程序名 argv[1]存储第一个参数
|
由main函数的定义可以看到,一个程序要在当前系统环境下,执行,需要知道程序名、相应的参数【可以没有】,一般情况下,调用程序是在特定的终端下,输入完成的路径或者相对路径就可以运行程序,要完成是这程序的调用是需要终端环境的支持,如果在程序中调用外部的程序或者脚本那就需要告诉父进程这个程序或者脚本在什么地方、需要输入的参数是那些、使用当前的环境变量还是自己指定环境变量,现在让我们来开始解析exec函数族。
首先需要知道, l 表示list,那么参数需要以列表的形式输入,就是单个逐次输入,形如
execl("/bin/ls","-al","/root/",(void *)0 );
|
v表示vector,即使向量,这里的向量就是指指针数组,所有的参数需要将其地址存入到这个指针数组当中,形如:
char *argv[4]; argv[0]="ls"; argv[1]="-al"; argv[2]="/root"; argv[3]=(void *)0; //最后一个参数指定为void型的空指针是为了告诉终端参数的个数 execv("/bin/ls",argv); //可见,l与v都是参数输入方式,所以只能选一种。可以认为l与v是互斥的
|
p表示当前环境变量,如果带这个字母的话,exec()函数的第一个参数就不需要输入完成的路劲名,只要输入可执行程序名或者脚本名,程序会根据当前的环境变量,自动去查找。
e表示使用指定的环境变量,形如:
char *argv[4]; char *env[2]; argv[0]="ls"; argv[1]="-al"; argv[2]="/root"; argv[3]=(void *)0; env[0]="/bin"; env[1]="/mybin"; execve(argv[0],argv,env);
|
现在用unix环境高级编程中的一张图片来表述这些区别。
基本的区别就这些,下边写一些小例子,
execl("/bin/ls","ls","-al",(void *)0); execlp("ls","ls","-al",(void *)0); execvp(argv[0],arg); execv("/bin/ls",arg); execle("ls","ls","-al",env);
|
阅读(1995) | 评论(0) | 转发(0) |