老生常谈exec函数族
1.exec函数说明
fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。
2.在Linux中使用exec函数族主要有以下两种情况
当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec 函数族让自己重生。
如果一个进程想执行另一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生。
exec家族
(1)int execl(const char *path, const char *arg, ......);
(2)int execle(const char *path, const char *arg, ...... , char * const envp[]);
(3)int execv(const char *path, char *const argv[]);
(4)int execve(const char *filename, char *const argv[], char *const envp[]);
(5)int execvp(const char *file, char * const argv[]);
(6)int execlp(const char *file, const char *arg, ......);
其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。
它们之间的区别:
第一个区别是:
前四个取路径名做为参数,后两个取文件名做为参数,如果文件名中不包含 “/” 则从PATH环境变量中搜寻可执行文件, 如果找到了一个可执行文件,但是该文件不是连接编辑程序产生的可执行代码文件,则当做shell脚本处理。
第二个区别:
前两个和最后一个函数中都包括“ l ”这个字母 ,而另三个都包括“ v ”, " l "代表 list即表 ,而" v "代表 vector即矢量,也是是前三个函数的参数都是以list的形式给出的,但最后要加一个空指针,如果用常数0来表示空指针,则必须将它强行转换成字符指针,否则有可能出错。,而后三个都是以矢量的形式给出,即数组。
最后一个区别:
与向新程序传递环境变量有关,如第二个和第四个以e结尾的函数,可以向函数传递一个指向环境字符串指针数组的指针。即自个定义各个环境变量,而其它四个则使用进程中的环境变量。
3.实例讲解:
char *const ps_argv[] ={"ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL};
char *const ps_envp[] ={"PATH=/bin:/usr/bin", "TERM=console", NULL};
execl("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
execv("/bin/ps", ps_argv);
execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL, ps_envp);
execve("/bin/ps", ps_argv, ps_envp);
execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
execvp("ps", ps_argv);
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>int main(int argc, char *argv[])
{//以NULL结尾的字符串数组的指针,适合包含v的exec函数参数char *arg[] = {"ls", "-a", NULL};/*** 创建子进程并调用函数execl* execl 中希望接收以逗号分隔的参数列表,并以NULL指针为结束标志*/if( fork() == 0 ){// in clild printf( "1------------execl------------\n" );if( execl( "/bin/ls", "ls","-a", NULL ) == -1 ){perror( "execl error " );exit(1);}}/***创建子进程并调用函数execv*execv中希望接收一个以NULL结尾的字符串数组的指针*/if( fork() == 0 ){// in child printf("2------------execv------------\n");if( execv( "/bin/ls",arg) < 0){perror("execv error ");exit(1);}}/***创建子进程并调用 execlp*execlp中*l希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志*p是一个以NULL结尾的字符串数组指针,函数可以DOS的PATH变量查找子程序文件*/if( fork() == 0 ){// in clhild printf("3------------execlp------------\n");if( execlp( "ls", "ls", "-a", NULL ) < 0 ){perror( "execlp error " );exit(1);}}/***创建子里程并调用execvp*v 望接收到一个以NULL结尾的字符串数组的指针*p 是一个以NULL结尾的字符串数组指针,函数可以DOS的PATH变量查找子程序文件*/if( fork() == 0 ){printf("4------------execvp------------\n");if( execvp( "ls", arg ) < 0 ){perror( "execvp error " );exit( 1 );}}/***创建子进程并调用execle*l 希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志*e 函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境*/if( fork() == 0 ){printf("5------------execle------------\n");if( execle("/bin/ls", "ls", "-a", NULL, NULL) == -1 ){perror("execle error ");exit(1);}}/***创建子进程并调用execve* v 希望接收到一个以NULL结尾的字符串数组的指针* e 函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境*/if( fork() == 0 ){printf("6------------execve-----------\n");if( execve( "/bin/ls", arg, NULL ) == 0){perror("execve error ");exit(1);}}return EXIT_SUCCESS;
}
老生常谈exec函数族相关推荐
- exec函数族的使用
调用shell脚本命令:execlp("sh","sh","filename",(char*)0); exec用被执行的程序完全替换调用它的 ...
- linux-进程的替换exec函数族
文章目录 一.进程的替换 二.exec函数族 execl函数 execlp函数 execvp函数 一.进程的替换 exec族函数函数的作用: 我们用fork函数创建新进程后,经常会在新进程中调用exe ...
- Linux进程控制——exec函数族
1.简介 在Linux中,并不存在exec()函数,exec指的是一组函数,一共有6个,分别是: #include <unistd.h> extern char **environ; in ...
- 12.Linux:exec函数族
(1)exec函数说明 fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法.它可以根据指定的 ...
- UNIX再学习 -- exec 函数族
我们在讲,文件I/O的时候,简单提到过 exec 函数,讲到 vfork 的时候,也有用到.下面我们来详细介绍下它. 参看:UNIX再学习 -- 文件I/O 参看:UNIX再学习 -- 函数 for ...
- 【Linux系统编程】进程替换:exec 函数族
00. 目录 文章目录 00. 目录 01. exec函数族 02. 参考示例 2.1 execl函数示例 2.2 execv函数示例 2.3 execlp() 或 execvp()函数示例 2.4 ...
- linux操作系统之exec函数族
当我们想在进程中执行另外一个函数或程序时,可以使用exec函数.进程调用exec函数,则该进程中用户空间所有代码和数据会完全被新程序替换,但是不会创建新进程,因此进程id不会发生改变. 函数族的头文件 ...
- Linux系统编程--3(exec 函数族,僵尸进程和孤儿进程,wait和wait_pid回收子进程)
exec 函数族 fork 创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支) ,子进程往往要调用一种 exec 函数以执行另一个程序.当进程调用一种 exec 函数时,该进程的用户 ...
- exec函数族实例解析
转载:http://www.cnblogs.com/blankqdb/archive/2012/08/23/2652386.html fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相 ...
- 【Linux系统编程学习】Linux进程控制原语(fork、exec函数族、wait)
此为牛客Linux C++和黑马Linux系统编程课程笔记. 1. fork函数 1.1 fork创建单个子进程 #include<unistd.h> pid_t fork(void); ...
最新文章
- Python调用外部程序——os.system()和subprocess.call()
- HDU 1517 A Multiplication Game
- 学习记录2-Python中的注册器模块
- Javascript的面对对象的理解 【上】(prototype,函数和对象等概念)
- 黑盒测试概念简述,黑盒测试优缺点、黑盒用例设计方法简单介绍及黑盒测试方法使用总结
- Python 列表 count( )方法
- sdl2 opengl d3d9的mipmap和各项异性过滤渲染
- SQL语句备查(引用)
- java中class.forName(str)的作用
- php define函数
- Vs2010 上的配置Opencv2.2
- xshell4连接ubuntu20.04失败,提示“找不到匹配的key exchange算法“
- rtl驱动 ubuntu 禁用_Ubuntu下成功安装台式机网卡realtek的rtl8188eu芯片驱动并实现AP功能...
- linux tcp调优
- BZOJ4484 JSOI2015最小表示(拓扑排序+bitset)
- Trait method *** has not been applied, because there are collisions with other trait methods on
- 艾司博讯:拼多多网店账号出现异常该怎么解决?
- matlab怎么生成三维等值线图,matlab画三维等值线图
- 【Flutter实战】定位装饰权重组件及柱状图案例
- python torch exp_PyTorch官方中文文档:torch
热门文章
- Android中实现两次点击返回键退出本程序
- 【SICP练习】80 练习2.52
- android中的MotionEvent 及其它事件处理
- javaScript原型链继承
- oracle修改只读数据库中,如何在oracle中创建只读数据库链接
- markdown 文档转 word
- python网络爬虫实践_第18,Python网络爬虫实践(1)
- 用策略屏蔽135 139 445 3389端口+网络端口安全防护技 .
- IntelliJ 中类似于Eclipse ctrl+o的是ctrl+F12
- Linux学习---新建文件,查看文件,修改权限,删除