关于execlp的一些参考文献

来自三线的随记
Admin讨论 | 贡献2019年3月27日 (三) 17:54的版本 (后记完善,加入我的看法)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

无意中看到一篇关于C语言execlp函数的参数解释文章,有点有趣,mark!

原文

复制粘贴:

关于C execlp函数的理解

execlp(從PATH 環境變量中查找文件並執行)

相關函數

fork,execl,execle,execv,execve,execvp

表頭文件 #include<unistd.h>

定義函數 int execlp(const char * file,const char * arg,……);

函數說明

execlp()會從PATH 環境變量所指的目錄中查找符合參數file的文件名,找到後便執行該文件,然後將第二個以後的參數當做該文件的argv[0]、argv[1]……,最後一個參數必須用空指針(NULL)作結束。

返回值

如果執行成功則函數不會返回,執行失敗則直接返回-1,失敗原因存於errno 中。

錯誤代碼

參考execve()。

範例

范例
1

2

3

4

5

6

7

8

/* 執行ls -al /etc/passwd execlp()會依PATH 變量中的/bin找到/bin/ls */

#include<unistd.h>

main()

{

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

}

//執行

//-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd

其实上面的描述很奇怪,如果能从PATH中找到第一个参数指定的文件,那何须第二个参数呢,没意义啊?

然后Google了下,看到了www.lslnet.com/linux/f/docs1/i34/big5260214.htm中别人同样的质疑。

这张帖子的楼主索性猜测:execlp函數在實際執行的時候根本沒有用到第二個參數。

说真的,这个猜测过于草率了。

楼下有一张回帖给出了一个反例:execlp("ls","flw","-?",(char *)0)。

应该是execlp("ls","flw","--help",(char *)0)吧,ls是Linux命令,-?是Windows的写法,不能同时运用,疑为他的笔误。这句语句在我电脑上的效果:

Usage: flw [OPTION]... [FILE]...

List information about the FILEs (the current directory by default).

Sort entries alphabetically if none of -cftuvSUX nor --sort. 

/** ↑注:重点在这里!↑ **/

自已在终端上永远试不出这个结果,因为明明调用的是ls命令,不可能显示出Usage: flw来。

再仔细看看上面关于这个函数的描述“然後將第二個以後的參數當做該文件的argv[0]、argv[1]……”

我猛然想到了以前说过main函数是可以传入参数的,我于是尝试了这样的代码:

尝试
1

2

3

4

5

6

7

8

int main(int num_args,const char* args[])

{

    for(int i=0;i<num_args;++i)

    {

        std::cout << args[i] << std::endl;

    }

        return 0;

}

在终端而不是IDE里运行这个程序,运行的时候给他带点参数,结果自己打的命令出现的在args[0]的位置,后面的参数出现在了args[1],args[2],args[3]....的位置,可见C程序总会把你运行这个程序用的命令传入args[0]。这样这个问题就解开了。execlp第一个参数是让程序从PATH中找到指定程序运行,第二个参数将传入这个程序的args[0]。

而execlp("ls","flw","--help",(char *)0)出现Usage: flw,是因为ls命令在显示帮助的时候会动用args[0],这么设计很正常,因为如果用户打错了命令,总希望用最接近他命令的方式指导他怎么做才对,直接使用他的命令是最方便的。平时args[0]几乎总是等于ls,这是因为ls在PATH中,没必要指示他的位置,但如果使用/bin/ls这样的命令,就可以看出来了。

后记

后来对前两个参数进行多次更改测试,得出结果,大多数linux命令,使用help参数显示出来的提示中

Usage *** [options]

***一般都是一个变量,指向了第二个参数,即args[0]

例如execlp("ps","abcd","--help",0)

回显结果就包括

Usage:

abcd [options]

这个的原因在上文最后一段也有编者的一个说明,有意思

想起PHP在终端模式下,如果dump出所有args,也有类似效果来着,有空补坑