一、函数族使用场合
exec函数族主要与vfork()函数配合使用.主要是在一进程中启动新的可执行程序.当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main()函数开始执行.
Attention!!!
1、调用exec函数族并不创建一新的进程,所以前后进程ID并不改变.exec只是用一个全新的程序替换了当前进程的正文、数据、堆和栈.
2、exec函数族提供了在一进程中启动另一程序执行的方法.另一程序可以是二进制文件,也可以是linux下任何可执行的脚本文件.
二、exec函数族列表
(1)int execl ( const char *path,const char *arg0,char *arg1,...,char *argn,NULL)
(2)int execle( const char *path,char *arg0,char *arg1,...,char *argn,NULL,char *const envp[])
(3)int execlp( const char *filename,char *arg0,char *arg1,...,NULL)
(4)int execv ( const char *path,char *const argv[])
(5)int execve( const char *path,char *const argv[],char *const envp[])
(6)int execvp( const char *filename,char *const argv[])
Attention!!!
1、这6个函数中以p结尾的函数取文件名作为参数.
2、当指定filename作为参数时,若filename中包含/,则将其视为路径名,否则就按PATH环境变量,在它所指定的目录中搜索可执行文件.
3、函数名中包含l的函数,它的参数是以列表(list)形式来表示,参数需要一个一个的输入,且以NULL为结束参数.
4、函数名中包含v的函数,它的参数是以矢量(vector)形式来表示,因此输入参数时需要先构造指针数组,然后将数组地址作为函数的参数.
5、函数名中包含e的函数,启动某个可执行文件后,会将新的环境变量值赋给可执行文件.但退出进程后,环境变量恢复原值.
6、函数名种包含p的函数,它的参数是以文件名(filename)形式来表示,系统会根据环境变量PATH所指的目录中查找符合参数filename的文件名.
三、应用实例
(1)函数execl()
函数功能:利用execl函数来启动某路径下的可执行程序,并可以向该可执行程序传递参数.
返 回 值:若执行成功则函数不会返回,执行失败则返回-1.
注意事项:向可执行程序中传递参数时,最后一个参数必须是NULL,以表示参数传递的结束.
应用例程:利用execl()函数来启动linux中/bin/ls的可执行程序,并向该可执行程序中传递3个参数.
#include
#include
#include
int main(int argc,char *argv[])
{
execl("/bin/ls","ls","-a","-l","-h",NULL); //需要加路径
return 0;
}
执行效果:
[root@localhost lishuai]# gcc execl.c -o execl -Wall -O2 -g
[root@localhost lishuai]# ./execl
//在当前目录下执行了可执行程序execl后,系统会启动/bin目录下的ls命令,这样会打印处当前目录下所有文件
[root@localhost home]# ../lishuai/execl
//在当前目录下执行了可执行程序execl后,系统会启动/bin目录下的ls命令,这样会打印处当前目录下所有文件
Attention!!!
1.execl()参数列表中必须以NULL为结束标志.
2.建议将可执行程序名(比如ls)也作为execl()函数的参数.
(2)函数execle()
函数功能:利用execle函数来启动某路径下的可执行程序,并将新的环境变量值赋给该可执行程序.
返 回 值:若执行成功则函数不会返回,执行失败则返回-1,且失败原因存放在全局变量errno中.
注意事项:1、向可执行程序中传递参数时,第二个参数必须以NULL结束.
2、进程结束后,环境变量恢复原值.
3、建议将可执行程序名(比如test)也作为execle()函数的参数.
应用例程:利用execle()函数来启动Linux中某一可执行程序,并将新的环境变量值赋给该可执行程序.
//execle()函数体
#include
#include
#include
void main(void)
{
char *env[]={"USER=LISHUAI","PATH=/bin/:/usr/bin/:","JIA=WUZHI",NULL};
execle("test","test",NULL,env);
}
//当前目录下的test.c程序.执行时,需要编译该程序.
#include
#include
#include
int main(void)
{
printf("USER=%s\n",getenv("USER"));
printf("PATH=%s\n",getenv("PATH"));
printf("JIA=%s\n",getenv("JIA"));
return 0;
}
执行效果:
[root@localhost lishuai]# gcc execle.c -o execle -Wall -O2 -g
[root@localhost lishuai]# ./execle
[root@localhost lishuai]# gcc test.c -o test -Wall -O2 -g
USER=LISHUAI
PATH=/bin/:/usr/bin/:
JIA=WUZHI
Attention!!!
利用execle()函数来启动执行可执行文件test时,将Linux系统新的环境变量值赋给了该文件.
(3)函数execlp()
函数功能:利用execlp函数来启动某个可执行程序,并可以向该可执行程序传递参数.
返 回 值:若执行成功则函数不会返回,执行失败则返回-1,且失败原因存放在全局变量errno中.
注意事项:1、向可执行程序中传递参数时,最后一个参数必须是NULL,以表示参数传递的结束.
2、与函数execl()的区别在于,execlp()函数会从PATH环境变量所指的目录中查找符合参数filename的文件名,找到后便执行该文件.
3、建议将可执行程序名(比如ls)也作为execlp()函数的参数.
应用例程:利用execl()函数来启动linux中/bin/ls的可执行程序,并向该可执行程序中传递3个参数.
#include
#include
#include
int main(void)
{
execlp("ls","ls","-a","-l","-h","/etc/profile",NULL); //直接加文件名
return 0;
}
执行效果:
[root@localhost lishuai]# gcc execlp.c -o execlp -Wall -O2 -g
[root@localhost lishuai]# ./execlp
//在当前目录下执行了可执行程序execlp后,系统会根据PATH环境变量所指的目录中查询ls命令并执行,这样系统会将文件/etc/profile以参数-a -l -h的方式列出.
(4)函数execv()
函数功能:利用execv函数来启动某路径下的可执行程序,并可以向该可执行程序传递参数.
返 回 值:若执行成功则函数不会返回,执行失败则返回-1,且失败原因存放在全局变量errno中.
注意事项:1、该函数与execl()完全一致,区别在于前者的参数存放在指针数组中,而后者参数需要一一列出.
2、指针数组中的参数列表中,最后一个参数必须是NULL,以表示参数传递的结束.
3、建议将可执行程序名(比如ls)也作为execv()函数的参数.
应用例程:利用execl()函数来启动linux中/bin/ls的可执行程序,并向该可执行程序中传递3个参数.
#include
#include
#include
int main(void)
{
char *p[]={"ls","-a","-l","-h",NULL};
execv("/bin/ls",p); //需要加路径
return 0;
}
[root@localhost lishuai]# gcc execv.c -o execv -Wall -O2 -g
[root@localhost lishuai]# ./execv
//在当前目录下执行了可执行程序execv后,系统会启动/bin目录下的ls命令,这样会打印处当前目录下所有文件
(5)函数execve()
函数功能:利用execve函数来启动某路径下的可执行程序,并将新的环境变量值赋给该可执行程序.
返 回 值:若执行成功则函数不会返回,执行失败则返回-1,且失败原因存放在全局变量errno中.
注意事项:1、向可执行程序中传递参数时,第二个参数必须以NULL结束.
2、进程结束后,环境变量恢复原值.
3、建议将可执行程序名(比如test1)也作为execve()函数的参数.
4、该函数与execle()完全一致,区别在于前者的参数存放在指针数组中,而后者参数需要一一列出.
应用例程:利用execve()函数来启动Linux中某一可执行程序,并将新的环境变量值赋给该可执行程序.
//execve()函数体
#include
#include
#include
void main(void)
{
char *env[]={"USER=LISHUAI","PATH=/bin/:/usr/bin/:","GONGSI=AIPU",NULL};
char *p[]={"test1",NULL};
execve("test1",p,env);
}
//当前目录下的test1.c程序.执行时,需要编译该程序.
#include
#include
#include
int main(void)
{
printf("USER=%s\n",getenv("USER"));
printf("PATH=%s\n",getenv("PATH"));
printf("JIA=%s\n",getenv("JIA"));
return 0;
}
执行效果:
[root@localhost lishuai]# gcc execve.c -o execve -Wall -O2 -g
[root@localhost lishuai]# ./execve
[root@localhost lishuai]# gcc test1.c -o test1 -Wall -O2 -g
USER=LISHUAI
PATH=/bin/:/usr/bin/:
GONGSI=AIPU
Attention!!!
利用execve()函数来启动执行可执行文件test1时,将Linux系统新的环境变量值赋给了该文件.
(6)函数execvp()
函数功能:利用execvp函数来启动某个可执行程序,并可以向该可执行程序传递参数.
返 回 值:若执行成功则函数不会返回,执行失败则返回-1,且失败原因存放在全局变量errno中.
注意事项:1、与函数execlp()的区别在于,前者的参数存放在指针数组中,而后者参数需要一一列出.
2、该函数的第二个参数是指针数组,最后一个元素必须是NULL,以表示参数传递的结束.
3、建议将可执行程序名(比如ls)也作为execvp()函数的参数.
4、第一个参数是可执行程序的文件名,而不需要加上路径,系统会根据环境变量PATH的值来找到该可执行文件.
应用例程:利用execvp()函数来启动linux中/bin/ls的可执行程序,并向该可执行程序中传递3个参数.
#include
#include
#include
int main(void)
{
char *p[]={"ls","-a","-l","-h",NULL};
execvp("ls",p); //直接加文件名
return 0;
}
[root@localhost lishuai]# gcc execvp.c -o execvp -Wall -O2 -g
[root@localhost lishuai]# ./execvp
//在当前目录下执行了可执行程序execvp后,系统会启动/bin目录下的ls命令,这样会打印处当前目录下所有文件