目录
[1 进程 -- exec函数族](#1 进程 – exec函数族)
[1.1 exec函数族特点](#1.1 exec函数族特点)
[1.2 进程 -- execl / execlp使用方法](#1.2 进程 – execl / execlp使用方法)
[1.3 进程 -- execv / execvp](#1.3 进程 – execv / execvp)
[2 进程 -- system](#2 进程 – system)
[3 exec族要点演示](#3 exec族要点演示)
掌握:exec函数族、system
1 进程 -- exec函数族
执行程序,通孔ps -elf发现,父进程是bash。这意味着该进程是由一个 bash shell 中启动的。
1.1 exec函数族特点
- 进程调用exec函数族执行某个程序
- 进程当前内容被指定的程序替换(重要特点)
- 实现让父子进程执行不同的程序(fork父子进程执行的是一个程序,下面是操作方法即原理)
-父进程创建子进程
-子进程调用exec函数族
-父进程不受影响
1.2 进程 -- execl / 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中查找(需要环境变量中添加)
示例1:
执行ls命令,显示/etc目录下所有文件的详细信息
if(execl("/bin/ls", "ls", "-a", "-l", "/etc", NULL) < 0){
perror("execl");
}
if(execlp("ls", "ls", "-a", "-l", "/etc", NULL) < 0){
perror("execlp");
}
0号参数即使命令本身,后面再加其他参数
最后参数必须加NULL空指针
cpp
#include <stdio.h>
#include <unistd.h>
int main(){
printf("before exec\n");
if(execlp("ls","ls","-a","-l","./",NULL)<0){
perror("execl");
}
}
1.3 进程 -- execv / execvp
#include <unistd.h>
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
成功时执行指定的程序;失败时返回EOF
arg... 封装成指针数组的形式
示例:
执行ls命令,显示/etc目录下所有文件的详细信息
char *arg[] = {"ls", "-a", "-l", "/etc", NULL};
if(execv("/bin/ls", arg) < 0)
{
perror("execv");
}
if(execvp("ls", arg) < 0)
{
perror("execvp");
}
#include <stdio.h>
#include <unistd.h>
int main(){
char *agv[] = {"ls","-a","-l","./",NULL};
if(execv("/bin/ls",agv)<0){
perror("execv");
}
}
linux@linux:~/Desktop$ ./a.out
total 24
drwxr-xr-x 2 linux linux 4096 Sep 18 10:32 .
drwxr-xr-x 22 linux linux 4096 Sep 18 10:32 ..
-rwxrwxr-x 1 linux linux 7330 Sep 18 10:32 a.out
-rw-rw-r-- 1 linux linux 184 Sep 16 11:24 fork.c
-rw-rw-r-- 1 linux linux 157 Sep 18 10:32 test.c
linux@linux:~/Desktop$ ls -a -l ./
total 24
drwxr-xr-x 2 linux linux 4096 Sep 18 10:32 .
drwxr-xr-x 22 linux linux 4096 Sep 18 10:32 ..
-rwxrwxr-x 1 linux linux 7330 Sep 18 10:32 a.out
-rw-rw-r-- 1 linux linux 184 Sep 16 11:24 fork.c
-rw-rw-r-- 1 linux linux 157 Sep 18 10:32 test.c
linux@linux:~/Desktop$
2 进程 -- system
#include <stdlib.h>
int system(const char *command);
成功时返回命令command的返回值;失败时返回EOF
当前进程等待command执行结束后才继续执行
其原理也是fork的子进程,执行完不会被替代
示例;
#include <stdio.h>
#include <stdlib.h>
int main(){
system("ls -a -l ./");
}
3 exec族要点演示
示例
cpp
//a.out
#include <stdio.h>
int main(int argc,char **argv){
printf("hello world %s,%s\n",argv[1],argv[2]);
}
#include <stdio.h>
#include <unistd.h>
//test
#include <stdio.h>
#include <unistd.h>
int main(){
printf("before exec\n");
if(execlp("./a.out","./a.out","abc","def",NULL)<0){
perror("execv");
}
printf("after exec\n");
}
printf没有执行,因为a.out把程序全部替换了。
如果想不被替换?
可以写一个子程序,使用exec
cpp
#include <stdio.h>
#include <unistd.h>
int main(){
pid_t pid;
printf("before exec\n");
pid = fork();
if(pid==0){
if(execl("/bin/ls","-a","-l","./",NULL)<0){
perror("execl");
}
}
printf("after execl\n");
}
printf被打印出来了。