我正在用C编写一个shell,我很难理解execvp(filepath,argv)所需的filepath参数。
如果输入的用户希望在当前目录中运行ls -a .比方说/home/user1 ..。在该目录中运行filepath和argv的ls是什么?
filepath是从/home/user1执行命令的目录,还是是命令的位置/bin/ls
发布于 2013-10-06 04:19:25
在当前目录中运行/bin/ls的 -a:
在C程序启动时,与argv传递到main()的内容相同,但NULL终止,路径与argv[0]相同。
char* argv[] = { "/bin/ls", "-a", NULL };
execvp(argv[0], argv);发布于 2013-10-06 05:05:57
filepath参数的execvp()可以采取两种形式之一-它包含一个斜杠或它不包含斜杠。
用斜杠
filepath参数指定可执行文件的路径名,或者是绝对名称(以斜杠开头),或者是相对名称(不以斜杠开头,而是包含斜杠)。execvp()函数不会对参数进行任何更改,并且假设名为“存在”的文件是可执行的,则程序将被执行(或不执行)。
无斜线
filepath参数指定“简单”名称,如ls。然后,excevp()函数试图执行一个名为ls的程序,该名称位于$PATH环境变量中列出的目录之一。p在execvp()中是用于“path”的,就像在路径查找中一样。
应用理论
如果用户将ls -a键入一个shell,则执行该操作的通常方法是创建一个字符指针数组,该数组相当于:
char *argv[] = { "ls", "-a", 0 };
execvp(argv[0], argv);execvp()现在将执行基于路径的分析,并尝试从$PATH中列出的目录之一执行ls。
如果用户将/bin/ls -a键入一个shell,那么执行该操作的通常方法是创建一个字符指针数组,该数组相当于:
char *argv[] = { "/bin/ls", "-a", 0 };
execvp(argv[0], argv);execvp()现在将执行指定的绝对路径名,因为这是用户请求的内容(相对于/usr/bin/ls或/usr/local/bin/ls)。
请注意,处理过程实际上是相同的--将命令行拆分为word;每个单词成为以空指针结束的字符指针数组的一个元素,并将第一个单词作为'filepath‘参数传递给execvp(),整个数组作为第二个参数传递。
显然,shell可以缓存实际可执行文件的位置,许多shell也可以缓存,这样execvp()就不必尝试查找程序(而shell不调用execvp(),而通常使用可执行文件的绝对路径名调用execv()。但这不是必要的,它是一种优化。
还要注意,没有什么可以阻止你:
char *argv[] = { "/honky/tonk/toys", "-a", 0 };
execvp("ls", argv);现在,argv[0]应该是"/honky/tonk/toys"而不是ls,因为运行的应该是ls可执行文件。在/proc中找到什么取决于系统中是否有/proc (例如,Mac不支持它),但是指向二进制文件的符号链接应该是到/bin/ls的链接。在Linux上,您会发现ps报告二进制名称(ls),尽管/proc/PID/cmdline包含原始参数(因此argv[0]是/honky/tonk/toys)。这是否好取决于您的观点,但整个世界都不是Linux。
https://stackoverflow.com/questions/19205316
复制相似问题