未分类

UNIX execlp函数(转)

在《UNIX环境高级编程》一书中,讲到exec函数及其使用,其中有一个例子,简单来说就是这样:

execlp(“ls”, “ls”, “-al”, (char *)0);

其输出结果就跟我们在终端里输入ls命令得到的结果一样。

在说疑问之前,先看函数的定义:

int execlp(const char file, const char *arg, … / (char *) NULL */);

其中第一个参数file指向可执行文件名称,因为execlp()函数会从系统PATH路径中寻找相应命令,所以不需要带完整路径;

第二个参数之后就都是传给可执行文件的参数,类似main函数的args[],只是最后一个参数必须为空字符指针;

疑问是这样的,既然第一个参数是指示可执行文件的名称,那么对于某些程序/命令,它不需要参数那是否就可以省略呢?比如ls,我们在终端中不给参数argv[0],它也能运行成功。

其实这个疑问还是很好解释的,《UNIX环境高级编程》一书中有提到,当内核起动C程序时会使用一个exec函数(7.2 main函数 ),而我们也知道,shell执行命令的方式就是fork+exec,所以我们执行ls命令不带参数并非代表没有这个参数,argv[0]这个参数系统还是会传递给exec函数的,我们可以做个试验

int main(int num_args, const char* args[])
{
​ for(int i = 0; i < num_args; ++i)
​ {
​ printf(“args[%d] = %s\n”, i, args[i]);
​ }
​ return 0;
}

编译后执行该程序

$./a.out

args[0] = ./a.out

由此可见,我们执行./a.out,本意是指示可执行程序的路径和名称(对应execlp中的file指针),看起来不带参数,但args[0]还是存在;同理我们执行ls,不带参数,但ls还是能从系统中得到arg[0]这个参数。

至于这个参数是什么,那是另外一回事了,比如某些shell会将此参数设置为完全的路径名(8.9 exec函数)。

Leave a Reply

邮箱地址不会被公开。 必填项已用*标注