exec*系列函数(p129)
本质:用新的程序代替新的进程,可以指定要运行程序的文件
- 系统调用fork创建子进程时,子,父进程有相同的代码段,如果希望运行另外一个新的程序,则需要调用exec*系列函数。
- 调用fork之后,子进程调用exec*系列函数运行一个新的程序,它不会创建新的进程,而是用新的程序替换子进程的地址空间,代码段,数据,堆,栈,所以,新的pid不变,新进程从main函数开始。
- execlp调用失败时才会继续向下执行,所以可以直接在函数下一行写perror,exit,不需要if语句。
- l(list):命令行参数列表
- p(path):搜索file时使用path变量
- v(vector):使用命令行参数数组
- e(environment):使用环境变量数组,不使用进程原有的环境变量,设置新加载程序运行的环境变量。
- execve是一个系统调用,另外5个是库函数,实现这些库函数的代码中调用了系统调用execve
exec函数如下:
int execl(const char*path,const char *arg,...);
path:指定路径(相对/绝对路径)
arg:相当于命令行参数,最后加上NULL。
int execlp(const char*file,const char *arg,...);
函数名以p结尾,使程序名在PATH中搜索。
无p时,使用路径搜索。
int execle(const char*path,const char*arg,...,char*const envp[]);
int execv(const char*path,char*const argv[]);
argv:建立一个字符串数组,向新程序中传递命令行参数,以NULL结尾。
int execvp(const char*file,char*const argv[]);
int execve(const char*path,char*const argv[],char*const envp[]);
成功时:无返回,失败时:返回-1
- 执行系统可执行程序时优先用execlp
- 调用用户自定义的可执行程序:execl
代码如下:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4
5 int main()
6 {
7 pid_t pid = fork();
8 if(pid == -1)
9 {
10 perror("fork error:");
11 exit(1);
12 }
13 else if(pid>0)
14 {
15 printf("我是父进程\n");
16 sleep(1);
17 }
18 else if(pid == 0)
19 {
20 printf("我是子进程\n");
21 execlp("ls","ls","-l","-a",NULL);
22 execl("./env","./env",NULL);运行可执行文件
23 execlp("env","./env",NULL);运行可执行文件
其中21-23,3种方法任选一种
注意:execl/execlp的第一个参数传可执行文件名
24 }
25
26 return 0;
27 }
在c程序中将输出定向到文件中
- dup2函数放在execlp函数之前,如果放在execlp函数之后,execlp函数已经开始执行程序了,所以在程序执行之前先继续重定向。
- 也可以在命令终端利用“>”进行输出重定向