Linux编程之exec类函数(参数详解+示例)

函数的使用

当想使得某一个进程去运行其他的程序时,我们就可以使用exec类函数

当进程调用一种 exec 函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行(当前进程剩下的程序代码便不再执行)。调用 exec 并不创建新进程,所以调用 exec 前后该进程的id并未改变。

当函数调用失败时,返回值为-1,调用成功则无返回值

函数分类

exec类函数共有6种,只有execve是系统调用,六种函数的参数各不相同,逐个分析

'l':list,列表,调用带有l的exec函数,需要将参数全部列出来

'v':vector,数组,调用带有v的exec函数,需要将参数存到一个指针数组中,再把数组首地址给函数

'p':path,环境变量,调用带有p的exec函数,需要保证将要跳转到程序在环境变量PATH中(不再PATH中函数调用会失败)

'e':environment,环境变量,暂时不明白,待更新...(以下内容暂不涉及)

函数的参数,这是很多初学者都迷惑的地方

看不懂的可以结合后面的例子

参数除了特殊的空指针外,其余的都是字符串形式

第一个参数

对于execl,execv 为将要跳转的程序的路径(同时包括程序名),可以是相对路径,也可以是绝对路径

对于execlp,execvp则为将要跳转的程序的程序名(!!!只有程序名,但是只有目标程序在环境变量PATH中才可以跳转成功),也可以给出路径,这时候的效果就分别和上面两个函数一样

第二个参数及以后

首先需要普及一下,main函数是有参数的

 int main(int argc,char* argv[])

剩下的参数其实是传递给目标程序的main函数(不需要传递argc,他是argv的大小,会自己计算),至少有一个非空,且最后要以NULL结尾,以便于实现程序间的交流,如果main函数中没有使用参数argv,那么参数其实可以随意写也可以直接用""

对于execl,execlp当然是将需要传递的参数全部列举在函数实参表里,不要忘了NULL

对于execv,execvp则需要将参数存在一个char类型的指针数组中(包括NULL),然后把指针数组首地址作为参数传递给execv类函数

下面是函数调用的示例,除了带e的没写,其他的都有:

关于环境PATH的查看和添加,可以参考blog:https://blog.csdn.net/qq_44786250/article/details/105325907

函数示例:

目标函数:

//test_1.c
#include<stdio.h>
int main()
{
	printf("我是test_1\n");
	return 0;
}
//test_2.c
#include<stdio.h>
int main(int argc,char*argv[])//argv为指针数组,用来存参数,argc为argv的大小,自动计算
{
	printf("我是test_2\n");
	for(int i=0;i<argc;i++)
		printf("argv[%d]=%s\n",i,argv[i]);
	return 0;
}

出击函数

//execl_1.c 
#include<stdio.h>
#include<unistd.h>
int main()
{
	printf("execl_1执行test_1程序:\n");
	if(execl("./test_1","",NULL)==-1)
		//第一个参数指明路径:相对路径或绝对路径
		//相对路径 ./为当前文件夹下,../为上一层文件夹 
		//后面为test_1中mian函数的参数,除NULL外至少有一个
		//最后必须使用NULL结尾
		perror("execl error");
		//调用成功无返回值
		//调用失败返回-1
	printf("若exec成功,我不会被执行\n");
	return 0;
}

//execl_2.c
#include<stdio.h>
#include<unistd.h>
int main()
{
	printf("execl_2执行test_2程序:\n");
	if(execl("./test_2","Hello","Good morning","Bye",NULL)==-1)
		perror("execl error");
	printf("若exec成功,我不会被执行\n");
	return 0;
}

//execv_1.c 
#include<stdio.h>
#include<unistd.h>
int main()
{
	char* buf[]={"",NULL};//将参数存到指针数组中,至少一个非空,且以空结尾
	printf("execv_1执行test_1程序:\n");
	if(execv("./test_1",buf)==-1)
		//第一个参数还是路径
		//第二个参数是指针数组名
		//直接使用数组传递预先存好的参数
		perror("execv error");
	printf("若exec成功,我不会被执行\n");
	return 0;
}

//execv_2.c
#include<stdio.h>
#include<unistd.h>
int main()
{
	char* buf[]={"Hello","Good moring","Bye",NULL};
	printf("execv_2执行test_2程序:\n");
	if(execv("./test_2",buf)==-1)
		perror("execv error");
	printf("若exec成功,我不会被执行\n");
	return 0;
}

//execlp_1.c
#include<stdio.h>
#include<unistd.h>
int main()
{
	printf("execlp_1执行 ls 指令:\n");
	if(execlp("ls","",NULL)==-1)
		//执行shell指令ls
		//第一个参数应该是PATH中的可执行文件名
		//不需要单独指明路径 
		//后面的参数与execl相同 
		perror("execlp error\n");
	printf("如果exec成功,此句不会执行\n");
	return 0;
}

//execlp_2.c
#include<stdio.h>
#include<unistd.h>
int main()
{
	printf("execlp_2执行 test_2 程序:\n");
	if(execlp("test_2","Hello","Good moring","Bye",NULL)==-1)
		//执行程序 test_2
		perror("execlp error\n");
	printf("如果exec成功,此句不会执行\n");
	return 0;
}

//execvp_1.c
#include<stdio.h>
#include<unistd.h>
int main()
{
	char* buf[]={"",NULL};//将参数存到指针数组中,至少一个非空,且以空结尾
	printf("execvp_1执行 ls 指令:\n");
	if(execvp("ls",buf)==-1)
		//第一个参数还是PATH中需要执行文件名
		//第二个参数是指针数组名
		//直接使用数组传递预先存好的参数
		perror("execvp error");
	printf("若exec成功,我不会被执行\n");
	return 0;
}

//execvp_2.c 
#include<stdio.h>
#include<unistd.h>
int main()
{
	char* buf[]={"Hello","Good moring","Bye",NULL};
	printf("execvp_2执行test_2程序:\n");
	if(execvp("test_2",buf)==-1)
		perror("execvp error");
	printf("若exec成功,我不会被执行\n");
	return 0;
}

在后续的博客中还有多进程配合exec函数的使用,欢迎大家观看和收藏

  • 19
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值