exec族函数的定义

定义

exec函数族提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行的脚本文件。

作用

我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。

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[]);

返回值

exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。

参数说明

path:可执行文件的路径名字
arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。

exec族函数实例

上面的定义已经解释得差不多了,接下来我们通过几个实例看看exec族函数究竟是怎么使用的。

execl函数


#include <stdio.h>
int main(int argc,char **argv){int i;for(i = 0;i < argc;i++){printf("argv[%d]: %s\n",i,argv[i]);}return 0;
}//这个demo非常简单,打印我们输入的参数,我们把这个文件命名为execlnewpro(可执行文件)======================分割线==================================#include <stdio.h>
#include <unistd.h>
int main(int argc ,char **argv){printf("before execl!\n");    if(execl("./execlnewpro","execlnewpro","abc",NULL) == -1){printf("execl filed!\n");perror("becasue");}printf("Execute after failure!\n");return 0;
}

下面这个demo使用execl函数,传入path也就是execlnewpro的路径(这里也可以写绝对路径),argv的第一个参数是我们需要的可执行文件名字,abc是第二个参数,结尾必须以NULL结尾。如果execl执行后返回-1,代表没有这个文件,会执行printf(“execl filed!\n”);这句话。我们可以通过perror来打印错误信息,那么紧接着会执行printf(“Execute after failure!\n”);,因为filed会原程序的调用点接着往下执行。 如果成功就直接去调用execlnewpro了。

插一句: perror 头文件 #include <stdio.h>
原型 void perror(const char *s);

打印结果如下图所示:


再比如说:

#include <stdio.h>
#include <unistd.h>int main(int argc ,char **argv){printf("before execl!\n");   if(execl("/bin/ls","ls","-l",NULL) == -1){printf("execl filed!\n");perror("becasue");}printf("Execute after failure!\n");return 0;
}

我们通过pwd命令查看ls的绝对路径,是在/bin/ls,调用ls并带着-l参数。通过execl会直接去调用ls -l命令,显示当前列表信息

execlp函数

那么execl函数后面加一个p是什么意思呢?p:使用文件名,并从PATH环境进行寻找可执行文件 ,,,带p的函数包括execlp、execvp、execvpe,如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。举个例子,PATH=/bin:/usr/bin

接着上面的demo我们继续,比如我现在想要获取时间,需要用到date命令,

#include <stdio.h>
#include <unistd.h>
int main(int argc ,char **argv){printf("before execl!\n");    if(execlp("date","date",NULL,NULL) == -1){printf("execl filed!\n");perror("becasue");}printf("Execute after failure!\n");return 0;
}

execlp函数会通过我们给出的data在系统变量中寻找文件,找到调用,否则error-1

插一句:whereis 想要查看命令,作用是查看命令的绝对路径比如whereis ls,可以查看ls的绝对路径
echo $ PATH Linux查看当前系统环境变来量
export PATH=$ PATH:(pwd查看当前的路径)
比如:
pwd(回车) /home/xxx/process
export PATH=$ PATH: /home/xxx/process ,这样就把当前路路径加到环境变量中了

结果上图:

execvp函数

那么带v的函数是什么意思呢? execv、execvp、execve,应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。

也就是在函数外面指定好指针数组,exec函数直接使用

看看demo


#include <stdio.h>
#include <unistd.h>int main(void){char *argv[] = {"ls","-l",NULL};if(execvp("ls",argv) == -1){printf("execl filed!\n");perror("becasue");}printf("Execute after failure!\n");return 0;
}//先指定好char *argv[] = {"ls","-l",NULL};,我们exec函数直接使用,一样的效果,目的一样,使用方法不一样

补充

那么我们使用fork函数和exec函数搭配使用是什么效果呢?之前我们说fork函数创建子进程也可以做不同的事情,那么这里就需要子进程返回后马上调用exec函数,不改变id去执行其他的可执行文件

学习笔记——Linux小应用修改配置文件
之前的章节写了修改配置文件的demo,那么在本节我们就把这个demo编译为demo7pro,编辑文件时config.txt

见代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>int main(){pid_t pid;int count = 0;int data = 0;pid =getpid();while(1){ printf("Please input the data!\n");scanf("%d",&data);if(data == 1){   pid = fork();if(pid > 0){wait(NULL);}if(pid == 0){execl("./demo7pro","demo7pro","config.txt",NULL); }       }else{printf("do nothing!\n");}   }return 0;
}

在这里我们使用execl函数直接去调用demo7pro,进而对config.txt的内容进行修改。而如果不使用execl函数,就要把之前章节的demo拿过来进行整合,代码量增多,且繁琐。

到这里config文件中的字段已经修改成功。

带e的一类exac函数,包括execle、execvpe,可以传递一个指向环境字符串指针数组的指针。 参数例如char *env_init[] = {“AA=aa”,”BB=bb”,NULL}; 带e表示该函数取envp[]数组,而不使用当前环境。

总结

l : 使用参数列表
p:使用文件名,并从PATH环境进行寻找可执行文件
v:应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。
e:多了envp[]数组,使用新的环境变量代替调用进程的环境变量

参考:https://blog.csdn.net/yychuyu/article/details/80173039?spm=1001.2101.3001.6650.3&depth_1-utm_relevant_index=4

学习笔记——exec族函数详解(execl, execlp, execle, execv, execvp, execvpe )相关推荐

  1. Linux 进程11【exec族函数(execl, execlp, execle, execv, execvp, execvpe)】

    linux进程-exec族函数(execl, execlp, execle, execv, execvp, execvpe) 原文链接:https://blog.csdn.net/u014530704 ...

  2. Linux进程5:exec族函数(execl, execlp, execle, execv, execvp, execvpe)总结及exec配合fork使用

    exec族函数(execl, execlp, execle, execv, execvp, execvpe)及exec配合fork使用 exec族函数函数的作用: 我们用fork函数创建新进程后,经常 ...

  3. exec族函数————execl, execlp, execle, execv, execvp, execvpe

    exec族函数 exec族函数的作用[^1] exec族函数的定义 函数原型: exac函数归为带l.带p.带v.带e 四类来说明参数特点 一.带l的一类exac函数(l表示list),包括execl ...

  4. linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)

    原文链接:https://blog.csdn.net/u014530704/article/details/73848573 exec族函数函数的作用: 我们用fork函数创建新进程后,经常会在新进程 ...

  5. 10.linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)

    1.exec族函数函数的作用: 1.exec族函数的作用: 我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序.当进程调用exec函数时,该进程被完全替换为新程序.因为 ...

  6. exec族函数详解(execl, execlp, execle, execv, execvp, execvpe )

    1.exec族函数的作用 exec函数族提供了一个在进程中启动另一个程序执行的方法.它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段.代码段和堆栈段,在执行完之后,原调用进 ...

  7. exec族函数(execl, execlp, execle, execv, execvp, execvpe)

    1.exec族函数的作用:我们用fork函数创建新进程后,经常会在新进程调用exec函数去执行另外一个程序. 当进程调用exec函数时,该进程被完全替换为新程序,因为调用exec函数并不创建新进程,所 ...

  8. Linux进程之exec镞函数的介绍(execl, execlp, execle, execv, execvp, execvpe)

    exec族函数函数的作用: 我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序.当进程调用exec函数时,该进程被完全替换为新程序.因为调用exec函数并不创建新进程, ...

  9. Linux进程 exec族函数(execl,execlp,execle,execv,execvp,execcvpe)

    exec族函数的作用 我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序.当进程调用exec函数时,该进程被完全替换为新程序.因为调用exec函数并不创建新进程,所以前 ...

最新文章

  1. 晶体管参数在实际使用中的意义
  2. AC自动机的使用案例
  3. Joy of Handcraft Gym - 102822J(线段树或差分)
  4. html怎么设置数据条的颜色,jQuery EasyUI 数据网格 – 条件设置行背景颜色 | 菜鸟教程...
  5. 加密相关(对称加密、非对称加密、信息摘要、数字签名、CA数字证书)
  6. Cocos2d-x学习笔记(9)(CCTextFieldTTF使用输入框)
  7. jedis java.lang.verifyerror_需要使用jfinal中的JedisPlugin的一些问题
  8. 比特币javascript私钥_javascript – 使用bitcoinjs发送比特币交易
  9. C语言数组和指针的区别
  10. 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档
  11. 腾达n6路由器虚拟服务器设置,腾达n6路由器怎么设置带宽控制
  12. RocketMQ-offset管理
  13. 如何查看mysql的gtid_mode_配置MHA开启主从同步的时候会提示从库gtid_mode为ON的状态...
  14. 你应该知道的三相电机知识
  15. JDBC链接中的问题
  16. mysql 慢_mysql 大事物commit慢造成全库堵塞问题
  17. TMC2240步进电机驱动芯片
  18. 通知之 Pending播放多媒体调用相册摄像头
  19. 铁威马F2-210配西数红盘,不仅是NAS那么简单
  20. 内网穿透神器NPS的使用

热门文章

  1. ASPICE详细介绍-3.ASPICE有多少能力等级?
  2. 微软办公软件Word,Excel,PPT一些常用操作
  3. double转int类型
  4. vs2017/2019 qt5 联合开发配置
  5. Golang高频问题(附答案)
  6. win10家庭版 安装 Docker
  7. IPVS调度算法之SED
  8. 开工大吉 | 2021一起牛!
  9. SQL注入原理及其简单演示
  10. 关于ping和telnet