exec函数族中的函数可以实现在一个进程中执行另一个进程,这个进程可以是可执行文件、shell命令、shell脚本
fork函数用于创建一个子进程,该子进程几乎拷贝了父进程的全部内容。
exec函数族提供了一种在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段。在执行完之后,原调用进程的内容除了进程号外,其他全部都被替换了。
可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。
exec函数族主要是将要执行的进程的用户空间覆盖之前进程的用户空间来执行自己的代码,所以之前进程的用户空间就会被覆盖且不会在执行
#include <unistd.h>
int execl(const char *path, const char *arg, .../* (char *) NULL */);
int execlp(const char *file, const char *arg, .../* (char *) NULL */);
int execle(const char *path, const char *arg, .../*, (char *) NULL*/,char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
功能:
在一个进程中执行另一个进程
参数:
path/file:
你要执行的进程的路径
l:
将要执行的进程按照每一个字符串的形式进行传参,最后一个位置补NULL标识结束
例如:ls -l /
"ls", "-l", "/", NULL
例如:./a.out
"./a.out", NULL
v:
将要执行的进程的命令保存在一个指针数组中再进行传参
例如:ls -l /
char *buf[4] = {"ls", "-l", "/", NULL};
例如:./a.out
char *buf[2] = {"./a.out", NULL};
p:
不带p的函数执行shell命令是必须跟当前要执行命令的绝对路径,带p无所谓
e:
带v的函数可以获取环境变量
返回值:
成功执行没有返回值
失败:
-1
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char const *argv[])
{
pid_t pid = fork();
if(pid == -1)
{
perror("fork error");
exit(1);
}
else if(pid > 0) //父进程
{
printf("父进程正在执行...\n");
wait(NULL);
}
else
{
printf("子进程正在执行...\n");
//*********************执行shell命令******************
//调用exec函数族中的函数执行另一个进程
//不带p的函数要执行shell命令时,第一个参数必须是绝对路径
//可以使用whereis 命令 查询shell命令的绝对路径
// if(execl("/bin/ls", "ls", "-l", "/", NULL) == -1)
// {
// perror("execl error");
// exit(1);
// }
//带p的函数执行shell命令时第一个参数可以是绝对路径也可以是相对路径
//if(execlp("ls", "ls", "-l", "/", NULL) == -1)
// if(execlp("/bin/mkdir", "mkdir", "-p", "mydir1/mydir2/mydir3/mydiir4", NULL) == -1)
// {
// perror("execl error");
// exit(1);
// }
//execvp的使用,需要定义一个指针数组来保存命令
// char *buf[] = {"ls", "-l", NULL};
// if(execvp("ls", buf) == -1)
// {
// perror("execvp error");
// exit(1);
// }
//*************执行一个C语言的可执行文件***********
//execlp("./hello", "./hello", NULL);
//*************执行一个shell脚本***********
execl("./myshell.sh", "./myshell.sh", NULL);
//只要能成功执行exec函数族中的函数,则无法在回到原本的进程执行
//因为新的进程覆盖了之前进程的用户空间
// printf("hello world\n");
}
return 0;
}