Appearance
通过 pstree指令 可以知道 Linux 上所有的线程都是从 init 线程 fork() 而来的。但 fork 子线程是父线程的拷贝,所以我们在 shell 里面运行一个程序,它不应该也是 shell 程序吗?此时有 exec 族函数,可以使我们 fork 的子线程替换为需要的程序。
exec() 函数族会替换当前进程的镜像,只有进程号保留。
函数原型
c
#include <unistd.h>
extern char **environ;
int execl(const char *pathname, const char *arg, ...
/* (char *) NULL */);
int execlp(const char *file, const char *arg, ...
/* (char *) NULL */);
int execle(const char *pathname, const char *arg, ...
/*, (char *) NULL, char *const envp[] */);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);execl()
@pathname 可执行文件的路径 @arg` 参数,可输入多个,通过 NULL 结束。
第一个参数是程序本身的名称,和 int main(..., char*args[]) 里的 args 是一样的。如果不一样也能运行,但是在 ps 中显示的名称就会按照 arg[0] 显示。
execlp()
和 execl一样,但只有输入文件名而不是完整路径,因为它有 environ 环境变量,存有当前路径。
execle()
和 execlp 一样,可以通过环境变量运行文件,但是环境变量可以不设置为全局变量,而是作为最后一个参数传入。
execv()
和 execl 一样,但是参数不再是单个的变量传入,而是通过一个字符串数组传入,数组最后一个需要是 NULL。
execvp()
参考 execlp
execvpe()
参考 execlpe
注意
缓冲区
替换的时候缓冲区会被清空,在终端(行缓存)运行结果正常的程序,输出到文本(全缓存)可能会出错。记得一定要 fflush 再 exec。这点和 fork() 是类似的。