exec函数族的基本用法

目录

  • exec()函数族-基础概念
  • exec()函数族参数分析—很重要
  • 关于fork()的第二种常见用法
  • 案例,在fork子进程调用exec函数族
exec()函数族-基础概念----man 3 exec

作用:execute a file,执行指定路径下的可执行文件
成员:execl(); execlp(); execle(); execv(); execvp(); execvpe()–不用了;
经常使用的是execve():
注:只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数

//参数是列表
execl(): arg0, arg1, ..., argn.
	int execl(const char *path, const char *arg, ...);
execlp():
	int execlp(const char *file, const char *arg, ...);
execle():
	int execle(const char *path, const char *arg,..., char * const envp[]);
//参数是数组
execv():
	int execv(const char *path, char *const argv[]);
execvp():
	int execvp(const char *file, char *const argv[]);
execvpe():好像弃用了,资料少。。
	int execvpe(const char *path, char *const argv[], char * const envp[]);
execve():
	int execve(const char *filename, char *const argv[],char *const envp[]);

举个例子:在这里插入图片描述

exec()函数族参数分析—很重要

(1):“l”和“v”表示参数是以列表还是以数组的方式提供,但是都要以NULL结尾,arg[0]:需要执行二进制程序的名字
(2):“p”表示这个函数的第一个参数是*path,就是以绝对路径来提供程序的
路径,也可以以当前目录作为目标
(3):“e”表示为程序提供新的环境变量,不需要给NULL
(4):所有参数要求全部来自man文档,请仔细阅读,如果出现错误或字符参数警告,你可以再仔细分析下这6个函数。
给一张简单直观图:
在这里插入图片描述
小案例:

#include <stdio.h>   
#include <stdlib.h>
#include <unistd.h>

/****************************************************************************************
**									exec函数族
//参数是列表
** execl(): arg0, arg1, ..., argn.
**	 int execl(const char *path, const char *arg, ...);
** execlp():
**	int execlp(const char *file, const char *arg, ...);
** execle():
**	int execle(const char *path, const char *arg,..., char * const envp[]);
//参数是数组
** execv():
**	 int execv(const char *path, char *const argv[]);
** execvp():
**	int execvp(const char *file, char *const argv[]);
** execvpe():
**	int execvpe(const char *path, char *const argv[], char * const envp[]);
**注意:execvpe要#ifdef __USE_GNU支持
	execl,execlp,execle:
		The first argument, by convention, should point to the filename associated with the file being executed,即arg0是可执行程序名字
		null-terminated strings(空终止字符串):The list of arguments must be terminated by a NULL pointer(结尾一定要是NULL)
	execv,execvp,execvpe:
		也必须满足上述两个要求,且以数组传入
	p:绝对路径来提供程序的路径	
	e:表示为程序提供新的环境变量       extern char **environ;
** RETURN VALUE
** 	The exec() functions only return if an error has have occurred.  The return value is -1
****************************************************************************************/ 


int main()
{
	if((execl("/linuxsystemcode/systemcode/pid/helloexecl","helloexecl","execl")) == -1)	//存在就调用helloexecl应用程序,不会再返回来了
	{
		perror("execl");
		exit(1);
	}
	
	printf("execl error!!!\n");						//正常情况下,是不会执行的
	return 0;
}

helloexecl.c

//helloexecl.c
#include <stdio.h>

int main(int argc, char *argv[])
{
	int i = 10;
	while(i--)
	{
		printf("%s %d.\n",argv[1], i);
	}
}

输出:
在这里插入图片描述

关于fork()的第二种常见用法

下面是程序框架:并发执行,谁先谁后执行完,并不清楚。父进程,子进程结束时间先后,会使输出不可控,你要在代码里更正
在这里插入图片描述

案例,在fork子进程调用exec函数族

下面的代码结合fork和6个exec族内函数的例子

#include <stdio.h>
#include <unistd.h>

//#define  _GNU_SOURCE											//execvpe才需要
//extern char **environ;											//新环境变量,下面全给NULL

/****************************************************************************************
**									exec函数族与fork
//参数是列表
** execl(): arg0, arg1, ..., argn.
**	 int execl(const char *path, const char *arg, ...);
** execlp():
**	int execlp(const char *file, const char *arg, ...);
** execle():
**	int execle(const char *path, const char *arg,..., char * const envp[]);
//参数是数组
** execv():
**	 int execv(const char *path, char *const argv[]);
** execvp():
**	int execvp(const char *file, char *const argv[]);
** execvpe():好像弃用了,资料少。。
**	int execvpe(const char *path, char *const argv[], char * const envp[]);
** execve():
** int execve(const char *filename, char *const argv[],char *const envp[]);
**注意:execvpe要#ifdef __USE_GNU支持
	execl,execlp,execle:
		The first argument, by convention, should point to the filename associated with the file being executed,即arg0是可执行程序名字
		null-terminated strings(空终止字符串):The list of arguments must be terminated by a NULL pointer(结尾一定要是NULL)
	execv,execvp,execvpe:
		也必须满足上述两个要求,且以数组传入
	p:绝对路径来提供程序的路径	
	e:表示为程序提供新的环境变量       extern char **environ;
** RETURN VALUE
** 	The exec() functions only return if an error has have occurred.  The return value is -1
****************************************************************************************/ 

int main(void)
{
	char *arg[]={"ls","-i",NULL};								//参数数组
	
//子进程1--int execl(const char *path, const char *arg, ...);
	if(fork() == 0)												//子进程调用exe函数族
	{
		printf("Forks 1 is Ok!!! : execl\n");
		if(execl("/bin/ls","ls","-i",NULL) == -1)
		{
			perror("execl error!!!\n");
			return 1;
		}
	}

	
//子进程2--int execlp(const char *file, const char *arg, ...);	
	usleep(50000);
	if(fork() == 0)
	{
		printf("Forks 2 is Ok!!! : execlp\n");
		if(execlp("ls","ls","-i",NULL) == -1)
		{
			perror("execlp error!!!\n");
			return 1;
		}
	}

	
//子进程3--int execle(const char *path, const char *arg,..., char * const envp[]);	
	usleep(50000);
	if(fork() == 0)
	{
		printf("Forks 3 is Ok!!! : execle\n");
		if(execle("/bin/ls","ls","-i",NULL, NULL) == -1)
		{
			perror("execle error!!!\n");
			return 1;
		}
	}

	
//子进程4--int execv(const char *path, char *const argv[]);
	usleep(50000);
	if(fork() == 0)
	{
		printf("Forks 4 is Ok!!! : execv\n");
		if(execv("/bin/ls",arg) == -1)
		{
			perror("execv error!!!\n");
			return 1;
		}
	}
		
		
//子进程5--int execvp(const char *file, char *const argv[]);
	usleep(50000);
	if(fork() == 0)
	{
		printf("Forks 5 is Ok!!! : execvp\n");
		if(execvp("ls",arg) == -1)
		{
			perror("execvp error!!!\n");
			return 1;
		}
	}


	//子进程6--int execve(const char *filename, char *const argv[],char *const envp[]);	
	usleep(50000);
	if(fork() == 0)
	{
		printf("Forks 6 is Ok!!! : execve\n");
		if(execve("/bin/ls",arg,NULL) == -1)
		{
			perror("execve error!!!\n");
			return 1;
		}
	}
	
	//子进程7--int execvpe(const char *path, char *const argv[], char * const envp[]);	
	// usleep(50000);
	// if(fork() == 0)
	// {
		// printf("Forks 7 is Ok!!! : execvpe\n");
		// if(execvpe("/bin/ls",arg,NULL) == -1)
		// {
			// perror("execvpe error!!!\n");
			// return 1;
		// }
	// }
	
	usleep(50000);							//不添加usleep(50000),终端会出现输出混乱
	return 0;
}

输出:
在这里插入图片描述
举个例子:注释掉最后的延时,输出
当然:修改延时也会有不同结果,还与代码量有关
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值