Linux函数exec
Linux函数exec
一、概述:
当用fork函数创建新的子进程后,子进程往往要调用一种exec函数以执行另一个程序。当程序调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用磁盘上的一个新程序替换了当前进程的正文段、数据段、堆段和栈段。
三、有7种不同的exec函数可供使用,它们常常被统称为exec函数。
#include <unistd.h>extern char **environ;1. int execl(const char *path, const char *arg, ...);
2. int execlp(const char *file, const char *arg, ...);
3. int execle(const char *path, const char *arg,..., char * const envp[]);
4. int execv(const char *path, char *const argv[]);
5. int execvp(const char *file, char *const argv[]);
6. int execvpe(const char *file, char *const argv[],char *const envp[]);
(我们只讲其中的execl,execlp,execvp)
参数:
*path:可执行文件的路径名。
*arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路经且arg必须以NULL结束。
*file:如果参数file中包含/,则就将其视为路径名,否则就按PATH环境变量,在它所指定的各目录中搜寻可执行文件。
函数名中的字符可以帮助理解和分辨:
l表示以参数列表的形式调用
v表示以参数数组的方式调用
e表示可传递环境变量
p表示PATH中搜索执行的文件,如果给出的不是绝对路径就会去PATH搜索相应名字的文件,如PATH没有设置, 则会默认在/bin,/usr/bin下搜索。
返回值:
如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
二、exec族函数的作用
exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。
与一般情况不同,exec函数族的函数执行成功后不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样。只有调用失败了,它们才会返回一个-1,从原程序的调用点接着往下执行。
三、实例1:在执行文件execl.c过程中调用execl,从而执行echoarg.c。
文件:echoarg.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;
}
只编译运行echoarg.c结果如下:
文件:execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execl\n");if(execl("./echoarg","file1","file2",NULL) == -1){printf("execl failed!\n");perror("why");}printf("after execl\n");return 0;
}
注:perror(s) 用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno的值来决定要输出的字符串。
若调用execl失败,返回-1,然后开始执行 printf(“after execl\n”);(打印"after execl")。
若成功则不执行 printf(“after execl\n”);(不打印"after execl")。
四、实例2:
我们都知道ls命令是linux下最常用的命令之一,用来列出目录下的文件。我们也可以调用execl来执行ls的命令。
ls指令运行结果:
我们可以通过whereis ls 指令来获得ls的文件路径。
execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execl\n");if(execl("/bin/ls","ls",NULL,NULL) == -1){printf("execl failed!\n");perror("why");}printf("after execl\n");return 0;
}
编译运行结果如下:
ls -l则会把详细列表打印出来:
可以尝试在execl函数的第三个参数写为“-l”:
execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execl\n");if(execl("/bin/ls","ls","-l",NULL) == -1){printf("execl failed!\n");perror("why");}printf("after execl\n");return 0;
}
编译运行结果如下:
五、实例3:获取日期和时间
Linux指令date 可以用来显示或设定系统的日期与时间
我们也可以调用execl函数来获取日期和时间(原理同实例2相同)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execl\n");if(execl("/bin/date","date",NULL,NULL) == -1){printf("execl failed!\n");perror("why");}printf("after execl\n");return 0;
}
编译运行结果如下:
六、在前面几个实例中调用函数execl第一个参数需要给出绝对路径,而函数execlp通过环境变量PATH查找到可执行文件(如实例6的“date”)。
实例6:execlp.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execlp\n");if(execlp("date","date",NULL,NULL) == -1){printf("execlp failed!\n");perror("why");}printf("after execlp\n");return 0;
}
实例7.execvp.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execvp\n");char *argv[] = {"data",NULL,NULL};if(execvp("date",argv) == -1) {printf("execvp failed!\n");perror("why");}printf("after execvp\n");return 0;
}
与execlp不同,execvp以参数数组的方式调用。
七、前面在讲函数fork和vfork中我们提到:
fork有以下两种用法。
(1) 一个父进程希望复制自己,使父进程和子进程同时执行不同的代码段。这在网络服务进程中是常见的—父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,使子进程处理此请求。父进程则继续等待下一个服务请求。
(2) 一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从返回后立刻调用exec。
所以我们可以把fork和exec配合使用。
实例8:通过调用fork创建子进程来对文件进行更改。
TEST.config
SPEED=3
LENG=9
SCORE=9
LEVEL=0
change.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(int argc,char *argv[])
{int fdsrc;char *readbuf=NULL;if(argc!=2){printf("param error\ni");exit(-1);}fdsrc=open(argv[1],O_RDWR);int size=lseek(fdsrc,0,SEEK_END);lseek(fdsrc,0,SEEK_SET);readbuf=(char *)malloc(sizeof(size)+8);int n_read=read(fdsrc,readbuf,size);char *p=strstr(readbuf,"LENG=");if(p==NULL){printf("not found\n");exit(-1);}p=p+strlen("LENG=");*p='5';lseek(fdsrc,0,SEEK_SET);int n_write=write(fdsrc,readbuf,strlen(readbuf));close(fdsrc);return 0;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>int main()
{pid_t pid;int data = 0;while(1){printf("please input a data\n");scanf("%d",&data);if(data==1){pid=fork();if(pid>0){wait(NULL);}if(pid==0){execl("./change","change","TEST.config",NULL);}}else{printf("wait...\n");}}return 0;
}
demo.c中调用当输入data = 1时,函数fork创建子进程,子进程调用execl来执行change(可执行文件),在change中对TEST.config进行更改。
文件TEST.config中"LENG"被修改成 了9。
Linux函数exec相关推荐
- linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)
原文链接:https://blog.csdn.net/u014530704/article/details/73848573 exec族函数函数的作用: 我们用fork函数创建新进程后,经常会在新进程 ...
- linux函数的阻塞与非阻塞IO及错误处理
linux函数的阻塞与非阻塞IO及错误处理 1.阻塞是指进程等待某一个事件的发生而处于等待状态不往下执行,如果等待的事件发生了则会继续执行该进程.调用系统阻塞函数可能会导致进程阻塞进入睡眠状态. 2. ...
- 在Linux使用exec执行命令时报的哪些错
问题1:find: paths must precede expression [root@localhost data]# find /oracle/backup/exp/data -name ex ...
- 中文在线Linux函数参考手册
Linux函数 http://www.iteedu.com/os/ http://net.pku.edu.cn/~yhf/linux_c/ linux命令 http://www.iteedu.com/ ...
- linux:exec族函数, exec族函数配合fork使用,system 函数,popen 函数
1.exec族函数 精彩博文: https://blog.csdn.net/u014530704/article/details/73848573 path: 比如说 ./a.out ...
- linux进程---exec族函数(execl, execlp, execv, execvp, )解释和配合fork的使用
exec族函数函数的作用: exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件.这里的可执行文件既可以是二 ...
- linux 进程函数替换,Linux使用exec函数实现进程替换的代码分享
这篇文章主要介绍了Linux 进程替换(exec函数)实现代码的相关资料,需要的朋友可以参考下 Linux 进程替换(exec函数)实现代码# include #include #include #i ...
- Linux进程—exec族函数 execl, execlp, execle, execv, execvp
exec族函数的作用: 我们用fork函数创建新进程后,经常会在新进程中调用exec族函数去执行新的程序:当该进程调用exec族函数时,该进程被替代为新程序,因为exec族函数并不创建新进程,所以前后 ...
- Linux进程 exec族函数(execl,execlp,execle,execv,execvp,execcvpe)
exec族函数的作用 我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序.当进程调用exec函数时,该进程被完全替换为新程序.因为调用exec函数并不创建新进程,所以前 ...
最新文章
- MicroPython支持图形化编辑了:Python Editor带你轻松玩转MicroPython
- 计算两个日期间隔天数(距离(2024-7-7)间隔:1999天)
- mkdir: 无法创建目录“/home/lj/.tldr“: 文件已存在
- 移动端采用Flexible将PX转换REM适配及开发中Retina屏1px边框的两种解决方案
- linux可配置哪些服务,不可不知 十大热门Linux服务器配置
- openerp 常见问题 OpenERP在哪储存附件?(转载)
- 工欲善其事必先利其器——MySQL数据库(2),查询操作
- python的字典合并有相同的_将列表中的重复项合并到python字典中
- python学习第十弹:宝可梦数据分析-平民最强
- windows 7计算机用户名和密码忘了,w7笔记本忘记开机密码怎么办_win7笔记本电脑忘记登录密码解决方法-系统城...
- 纸黄金投资之道――积小胜为大胜(就是别贪)
- 测试员,面对自己30岁后的下坡路,我们该何去何从?
- install在python里什么意思_python setup.py install是什么意思
- jq点击图片展示预览效果
- turtle 绘画实例1 画圆
- 类似Confluence的软件有哪些
- 三角波发生器电路图分析
- w ndows 10关机,Win10设置定时开关机休眠唤醒的方法
- INCREMENTAL BACKUP
- Urban Airship Android Client - Google GCM Push