Linux学习_exec和system函数

exec函数和system函数

exec函数(execute执行)

1.概念

  • 在用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序。不适合在父进程中调用。
  • 当进程调用一种exec函数时,该进程完全由新程序代替,替换原有进程的正文,而新程序则从其main函数开始执行。因为调用exec并不创建新进程,所以前后的进程ID并不改变。exec只是用另一个新程序替换了当前进程的正文(代码)、数据、堆和栈段。

2.函数原型:

#include <unistd.h>

int execl(const char *pathname, const char *arg0,.../*(char*)0*/); // (char*)0 意义为NULL
int execv(const char *pathname, char *const argv[]);

int execle(const char *pathname, const char *arg0,.../*(char*)0, char *const envp[]*/);
int execve(const char *pathname, char *const argv[], char *const envp[]);

int execlp(const char *pathname, const char *arg0,.../*(char*)0*/);
int execvp(const char *pathname, char *const argv[]);

返回:出错返回-1,成功则不返回
  • exec系列函数的注意点

    • execve函数为系统调用,,其余为库函数。执行execve,函数后面的代码不执行。

    • execlp和execlp函数中的pathname,相对和绝对路径均可使用,其他四个函数中的pathname只能使用绝对路径。相对路径一定要在进程环境表对应的PATH中。

    • argv参数为新程序执行main函数中传递的argv参数,最后一个元素为NULL。

    • envp为进程的环境表。

  • 六个函数都是以"exec"开头,后面的字母表示了其用法上的区别

后缀意义
‘l’(list)表面后面的参数列表是要传递给程序的参数列表,参数列表的第一个参数必须要是执行程序,最后一个参数必须是NULL。
‘p’(path)第一个参数可以是相对路径或程序名,如果无法立即找到要执行程序,那么就在环境变量PATH指定的路径中搜索。其他函数的第一个参数必须是绝对路径名。
‘v’(argv)表明程序的参数列表通过一个字符串数组来传递。这个数组和最后传递给程序的main函数的字符串数组argv完全一样。第一个参数必须要是执行程序,最后一个参数必须是NULL。
‘e’(enviro)用户可以自己设置程序接受一个设置环境变量的数组。
if( exec函数() < 0 ){
	//执行出错要返回
	perror("exec error");
	exit(1);
}
后续代码...//exec执行成功后,后续代码不会被执行

示例1:

/*
 * process_exec.c
 * 
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

char *cmd1 = "./fgetc练习";
char *cmd2 = "./1_sushu";
char *argv1 = "test.txt";

int main(int argc, char **argv)
{
	pid_t pid;
	
	/*第一个子进程*/
	if((pid = fork())<0){perror("fork error");exit(1);}
	else if(pid==0)
	{
		//子进程调用exec函数执行新的程序
		//问题语句:l 必须使用绝对路径,lp 可以使用相对路径
		//if(execl(cmd1, cmd1, argv1,NULL)<0) 
		if(execlp(cmd1, cmd1, argv1,NULL)<0)
		{perror("execl error");exit(1);}
		//子进程完全由新程序代替,以下子进程代码都不会执行
		else printf("execl %s success\n",cmd1);
		printf("after execl...\n");
	}
	wait(NULL);
	printf("-----------------------------------------\n");
	
	/*第二个子进程*/
	if((pid = fork())<0){perror("fork error");exit(1);}
	else if(pid==0)
	{
		char *argv[7]={cmd2,"1","2","3","4","5",NULL};
		if(execvp(cmd2, argv )<0)
		{perror("execl error");exit(1);}
	}
	wait(NULL);
	printf("-----------------------------------------\n");
	
	return 0;
}

输出:

请输入字符串,以@结尾:
abcdefghijkmnopqrstuvwxyz@
abcdefghijkmnopqrstuvwxyz@
-----------------------------------------
输入的数中素数和为:10
-----------------------------------------

system函数

1.函数原型

#include <stdlib.h>
int system(const char *command);
返回:成功返回执行命令的状态,出错返回-1
功能:简化exec函数的使用
  • system函数内部构建一个子进程,由子进程调用exec函数。
  • 等同于 /bin/bash -c “cmd” 或者 exec(“bash”,"-c",“cmd”);

案例:

/*
 * process_system.c
 */

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

char *cmd1="date"; //相对路径
char *cmd2="/bin/cal"; //绝对路径

int main(void)
{
	system("clear");
	system(cmd1);
	sleep(1);
	system(cmd2);
	
	return 0;
}

自己写system函数

/*
 * process_my_system.c
 * 
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

char *cmd1="date > s1.txt"; //'>'输出重定向
char *cmd2="cal > s2.txt";

void mysystem(char *cmd)
{
	pid_t pid;
	if((pid = fork())<0){perror("fork error");exit(1);}
	else if(pid==0)
	{
		if(execlp("/bin/bash", "/bin/bash",\
						"-c", cmd, NULL )<0)
		{perror("execlp error");exit(1);}
	}
	wait(0);
}

int main(void)
{
	mysystem("clear");
	mysystem(cmd1);
	mysystem(cmd2);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值