参考博文链接:https://blog.csdn.net/u014530704/article/details/73848573
exec族函数函数的作用:
我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。
exec族函数定义:
可以通过这个网站查询:linux函数查询
功能:
在调用进程内部执行一个可执行文件。可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。
函数族:
exec函数族分别是:execl, execlp, execle, execv, execvp, execvpe
函数原型:
#include <unistd.h>
extern char **environ;
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[]);
l : 使用参数列表
p:使用文件名,并从PATH环境进行寻找可执行文件
v:应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。
e:多了envp[]数组,使用新的环境变量代替调用进程的环境变量
返回值:
exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行
Linux进程
执行其他文件例如 此类文件需要提前编译在使用exec函数时绝对路径就是其编译后文件的路径
进程调用下程序查看 输入参数
//文件ps.c
#include <stdio.h>
int main(int argc,char *argv[])
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("argv[%d]: %s\n",i,argv[i]);
}
return 0;
}
=============================================
使用execl函数 ,调用ps -l
//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
printf("before execl\n");
if(execl("bin/ps","ps","-l",NULL) == -1) //使用whereis ps 查看ps的路径 第一个参数为执行文件的绝对路径
{
printf("execl failed!\n");
perror("why"); //用该函数来检查错误出处
}
printf("after execl\n");
return 0;
}
2、需注意,执行程序时注意其路径
int execlp(const char *file, const char *arg, ...);
如果不需要考虑其路径的,则需要使用execlp()函数,file 为文件名,通过当前PATH环境变量查找可执行文件。
如果可执行文件不在当前环境变量则需要添加执行文件所在的环境变量 PATH=$PATH:XXX
3、int execv(const char *path, char *const argv[]); 将后面三个参数放入数组
char *argv[]={ps,-l,NULL};
execv("ps",argv);
=========================================================
exec配合fork使用 实现当父进程检测到输入为1的时候,创建子进程把配置文件的字段值修改
一般写法
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc ,char **argv)
{
pid_t pid;
int data;
int F_fd;
while(1)
{
printf("please input your want \n");
scanf("%d",&data);
if(data == 1)
{
pid=fork();
if( pid > 0 )
{
wait(NULL);
}
if(pid == 0)
{
char *readbuf=NULL;
F_fd=open("config.txt",O_RDWR);
int size=lseek(F_fd,0,SEEK_END);
lseek(F_fd,0,SEEK_SET);
readbuf=(char *) malloc(sizeof(char)*size+8);
int n_read=read(F_fd,readbuf,size);
char *p=strstr(readbuf,"LENG=");
if(p == NULL)
{
printf("no found\n");
exit(-1);
}
p=p+strlen("LENG=");
*p='5';
lseek(F_fd,0,SEEK_SET);
int n_write=write(F_fd,readbuf,strlen(readbuf));
printf("chang sucess !\n");
close(F_fd);
exit(0);
}
return 0;
}
else
{
printf("error\n");
}
}
return 0;
}
使用execl函数 就不用使用exit()函数退出,其本身就会退出。
demo6.c 修改文件内容
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc ,char **argv)
{
int F_fd;
char *readbuf=NULL;
F_fd=open("config.txt",O_RDWR);
int size=lseek(F_fd,0,SEEK_END);
lseek(F_fd,0,SEEK_SET);
readbuf=(char *) malloc(sizeof(char)*size+8);
int n_read=read(F_fd,readbuf,size);
char *p=strstr(readbuf,"LENG=");
if(p == NULL)
{
printf("no found\n");
exit(-1);
}
p=p+strlen("LENG=");
*p='5';
lseek(F_fd,0,SEEK_SET);
int n_write=write(F_fd,readbuf,strlen(readbuf));
printf("chang success !\n");
close(F_fd);
return 0;
}
需要将上面的demo6.c 编译为demo6
if(pid == 0)
{
execlp("./demo6","demo6",NULL);
}
========================================================
采用输入指定编译文件 以及修改特定数字
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc ,char **argv)
{
int F_fd;
char *readbuf=NULL;
F_fd=open(argv[1],O_RDWR);
int size=lseek(F_fd,0,SEEK_END);
lseek(F_fd,0,SEEK_SET);
readbuf=(char *) malloc(sizeof(char)*size+8);
int n_read=read(F_fd,readbuf,size);
char *p=strstr(readbuf,"LENG=");
if(p == NULL)
{
printf("no found\n");
exit(-1);
}
char *c=argv[2];
p=p+strlen("LENG=");
printf("%s\n",argv[2]);
*p=*c;
lseek(F_fd,0,SEEK_SET);
int n_write=write(F_fd,readbuf,strlen(readbuf));
printf("chang success !\n");
close(F_fd);
return 0;
}
=============================
```c
```c
GAO=9
KUAN=9
LENG=1
GAO=9
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc ,char **argv)
{
pid_t pid;
int data;
int F_fd;
while(1)
{
printf("please input your want \n");
scanf("%d",&data);
if(data == 1)
{
pid=fork();
if( pid > 0 )
{
wait(NULL);
}
if(pid == 0)
{
execlp(argv[1],argv[2],argv[3],argv[4],NULL);
}
return 0;
}
else
{
printf("error\n");
}
}
return 0;
}
system 就是封装后execl后的函数 成功返回127 失败返回 -1.使用system()函数后其后面的程序还需执行。
```c
system("ps");
popen函数
比system 好用的是 可以命令结果输出
#include <stdio.h>
// size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
int main()
{
int n_read;
char readbuf[1024]={0};
FILE *fd;
fd= popen("ps","r"); // r 标准输出 W 标准输入
n_read=fread(readbuf,1,1024,fd);
printf("from readbuf %d byte\nThe follow is:%s",n_read,readbuf);
return 0;
}