文章目录
前言
夫志当存高远,慕先贤,绝情欲,弃疑滞,使庶几之志,揭然有所存,恻然有所感;忍屈伸,去细碎,广咨问,除嫌吝,虽有淹留,何损于美趣,何患于不济。若志不强毅,意不慷慨,徒碌碌滞于俗,默默束于情,永窜伏于平庸,不免于下流矣。——诸葛亮
一、exec族函数简介
1、函数格式
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
path和file表示有要执行的程序和包含路径的文件名:
arg 为参数序列,中间用逗号分隔;
啊如果v为参数列表;
envp 为环境变量列表
返回值 :exec函数族的函数执行成功后不会返回数值,因为调用进程的实体,
包括代码段等等都被新的内容取代,只留下进程ID等一些表面上的信息任保持原样,
只有调用失败后才会返回-1,从原程序的调用带你往下执行,同时会设置errno
在此只了解execl,execlp,execvp其他暂不了解
2、为什么需要exec函数
我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。
当进程调用exec函数时,该进程被完全替换为新程序。
因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。
二、exec函数使用
1、execl函数的使用
在终端输入
man execl #可以观察详细介绍
当我们输入错误文件夹时候会设置errno,同时打印if语句的内容:
用perror();可以解析错误消息
注意:文件路径可以用 whereis 来寻找
下图程序中打印 printf("Get date erro\r\n"); 表示excl执行文件失败,
然后从失败处往下继续执行,会执行到 printf("Try again\r\n");函数
perror();看出是没有找到文件的地址
修改正确的地址后观察现象,程序执行一半后继续执行date命令获取时间,且不在该进程下继续往下执行
2、execlp函数的是使用
上面介绍的execl函数输入参数时候要包括文件的命令,有些繁杂,
execlp可以直接在环境变量中寻找需要的参数命令,不用添加文件的路径
提示1 : 观察当前环境变量的路径
echo $PATH
提示二: 将当前路径添加到环境变量中去 (在其他文件路径也能执行当前路径可执行文件)
1.输入 pwd
观察当前的绝对路径
2、输入expor PATH=$PATH: “+ pwd下的文件路径“
3、输入 echo $PATH
可以观察到当前的文件路径被添加到环境变量中去
3、execvp函数的使用
三、exec族函数与fork函数的使用
实现功能:当父进程检测到输入为1的时候,创建子进程把配置文件的字段值修改掉
将文件修改参数的设置为 change 可执行文件 输入的参数是修改的文件名称
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char **argv)
{
if(argc != 2){
printf("输入文本参数有误\r\n");
printf("The argc = %d\r\n",argc);
exit(-1);
}
int fp; //定义文件的标识符
char *readBuf = NULL;
int size;
fp = open("./file.txt",O_RDWR|O_CREAT,0600);
if(fp != -1)
printf("Open file success!!!\r\n");
size = lseek(fp,0,SEEK_END);
lseek(fp,0,SEEK_SET);
readBuf = (char *)malloc(sizeof(char)*size +10);
int read_n = read( fp , readBuf , size);
// printf("%s\r\n",readBuf);
char *p=strstr(readBuf,"LENG=");
if(p == NULL){
printf("NOT found\r\n");
exit(-1);
}
*(p+strlen("LENG=")) = '6';
lseek(fp,0,SEEK_SET);
write(fp,readBuf,strlen(readBuf));
printf("文件更改成功!!!\r\n");
close(fp);
return 0;
}
在另一个文件中父进程创建子进程,在子进程中修改文件参数
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
pid_t pid;
int test;
while(1)
{
puts("请输入命令代码:\r\n");
scanf("%d",&test);
if(test == 1)
{
printf("代码正确\r\n");
pid = fork();
if(pid > 0){
wait(NULL);
}
else if( pid == 0){
execl("./change","change","file.txt",NULL);
}
}
else
puts("代码错误!!请重试\r\n");
}
}
执行结果:
四、system函数
system和exec函数的区别
1、system()和exec()都可以执行进程外的命令,system是在原进程上开辟了一个新的进程,但是exec是用新进程(命令)覆盖了原有的进程
2、system()和exec()都有能产生返回值,system的返回值并不影响原有进程,但是exec的返回值影响了原进程
五、popen函数
相比system函数的优点在于:
有返回值可以监控运行状态
使用更加简单,可以获取输出结果
可以利用popen得到文件的输出结果