学习内容
★ exec函数族
★ system命令
2. exec函数背景
fork创建进程之后,子进程和父进程执行相同的代码,但是在实际开发当中,我们希望父子进程执行不同的代码,所以exec函数的主要作用是执行指定的程序。
3. exec函数
进程调用exec函数族执行某个程序,进程当前内容被指定的程序替换时,实现让父子进程执行不同的程序。主要过程:
① 父进程创建子进程
② 子进程调用exec函数族
③ 父进程不受影响
3.1 execel、execlp函数
两个函数分别通过传递执行的程序路径(含执行程序)、执行的程序名称,执行指定的程序。
#include <unistd.h>
int execl(const char *path, const char *arg, …);
int execlp(const char *file, const char *arg, …);
成功时执行指定的程序;失败时返回EOF。
path 执行的程序名称,包含路径
arg… 传递给执行的程序的参数列表
file 执行的程序的名称,在PATH中查找
注意:两个函数区别execlp不需要写文件名全路径,在PATH查找(操作系统环境变量), 最后一个参数必须用空指针(NULL)作结束。进程当前内容被指定的程序替换,但进程号不变,第0个参数必须要写,虽然它没有使用。
例1
执行ls命令,显示当前目录下所有文件的详细信息
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv[])
{
pid_t pid;
pid = fork();
if (pid == 0) {
if (execl("/bin/ls","-a","-l","./",NULL)<0) {
perror("exec");
}
}
printf("after excel..\n");
}
![](https://i-blog.csdnimg.cn/blog_migrate/072b753f043d2968a064cf013e575ce3.jpeg)
程序执行后,先执行第行父进程(打印after excel ...),然后再执行子进程执行显示当前目录命令: ls -l,但是存在一个问题:子程序执行后没有退出控制台,需要按下回车键才能退出。
例2
执行ls命令,显示/etc目录下所有文件的详细信息
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv[])
{
pid_t pid;
pid = fork();
if (pid == 0) {
if (execlp("ls","-a","-l","/etc",NULL)<0) {
perror("exec");
}
exit(0);
}
printf("after excel..\n");
return -1;
}
参数1调用环境变量中的ls命令,组合起来其实就是:/etc ls -l 命令
3.2 execv 、execvp函数
两个分别通过将要执行的程序路径(含执行程序)、执行的程序名称保持至数组argv[],来执行指定的程序。
#include <unistd.h>
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
成功时执行指定的程序;失败时返回EOF。 arg… 封装成指针数组的形式
例3
使用execv函数执行ls命令,显示当前目录下所有文件的详细信息
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv[])
{
pid_t pid;
char *arg[] = {"ls", "a","-l","./",NULL};
pid = fork();
if (pid == 0) {
if (execv("/bin/ls",arg)<0) {
perror("exec");
}
exit(0);
}
}
例4
使用execvp函数执行ls命令,显示当前目录下所有文件的详细信息
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv[])
{
pid_t pid;
char *arg[] = {"ls", "a","-l","./",NULL};
pid = fork();
if (pid == 0) {
if (execvp("ls",arg)<0) {
perror("execvp");
}
exit(0);
}
}
例5
创建子进程执行test.c函数,主进程执行打印。
主函数exec5_t.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv[])
{
pid_t pid;
char *arg[] = {"a","101","102",NULL};
printf("before execvp...\n");
pid = fork();
if (pid == 0) {
if (execv("./test",arg)<0) {
perror("execvp");
}
}
printf("after execvp...\n");
}
test.c
#include <stdio.h>
int main(int argc, char **argv)
{
printf("This is test .. argv[1] = %s,argv[2]=%s\n",argv[1],argv[2]);
return 0;
}
执行结果
root@book-virtual-machine:/home/book/homework/lv5# ./exec5_t
before execvp...
after execvp...
This is test .. argv[1] = 101,argv[2]=102
4. 进程 – system
#include <stdlib.h>
int system(const char *command);
C 库函数 int system(const char *command) 把 command 指定的命令名称或程序名称传给要被命令处理器执行的主机环境,并在命令完成后返回。成功时返回命令command的返回值,失败时返回EOF。 当前进程等待command执行结束后才继续执行
例6
使用system命令显示系统根目录/下的文件详细信息。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, int **argv)
{
char command[50];
strcpy(command, "ls -l /");
system(command);
return 0;
}