关于execlp()函数及其参数问题

  • Post author:
  • Post category:其他


在《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 -al 的时候,对应到execlp中应该是 file,arg[0] 或是 file,arg[1] 呢?要完全对应应该输入ls ls -al,但这又不合法,所以最有可能是file, arg[1],那此时的 arg[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函数)。



版权声明:本文为yinshizhishi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。