Linux中不同版本exec函数区分

本文最后更新于:2022年3月19日 上午

该问题为OSTEP第五章进程API上的一个问题,在搜Stack overflow的时候发现一个很好记的答案,单独写一个博客记录一下

参考回答

  1. what-are-the-different-versions-of-exec-used-for-in-c-and-c

翻译摘抄

对于exec()函数,在C/C++中有以下几个不同的版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#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[]);

其中不同版本的区别通过函数名可以分为以下几个大类:

L和V

  • L:L在这里指的是list,执行的时候的将参数以类似如下方式传入:

    1
    execl(const char *pathname, const char *arg, ...)

    其中省略号代表了后续分别独立传入的参数,其中,第一个参数应是正在执行的文件关联的文件名,并且参数以空字符NULL作为结尾的判定。

  • V: V在这里指的是vector,执行的时候以char*的形式传入执行指令

    1
    int execv(const char *pathname, char *const argv[]);

    对于不确定传入参数的个数的时候,可以使用vector来执行程序。使用带v的函数的时候,首先传入的第一个pathname是指向可执行文件的路径,后面传入的argv[]中,第一个argv的位置上按习惯为可执行文件的名字,后面argv+1等参数则是实际需要调用的可执行文件的参数、

有的命令执行的时候,我们并不知道要传入的参数有几个,而有的命令则必须要一定数量的参数才能运行。通过分别调用带l或带v的函数,在不同的情况下执行某些特定命令很有用

E

E在这里指代的是Environment,在结尾带eexec()调用的时候的环境变量env与父进程的env并非一定相同,通过带e的函数即可在调用exec()的同时传入一个env供子进程使用

P

P在这里指的是系统环境变量中的PATH,含有pexec()在调用的时候会在系统变量的PATH当中寻找对应的可执行文件,而缺少pexec()在执行的时候,如果在当前目录下没有对应的文件名字,则需要传入目标可执行文件的绝对或相对路径。