execvp文件路径澄清

时间:2013-10-06 04:07:05

标签: c execvp

我正在用C语言写一个shell,我无法理解execvp(filepath,argv)所需的文件路径参数。

如果用户输入的内容想要在当前目录中运行ls -a ...请说/home/user1 ... filepathargv用于运行ls {1}}在所说的目录中?

filepath/home/user1执行命令的目录,还是命令的位置/bin/ls

2 个答案:

答案 0 :(得分:2)

filepath的{​​{1}}参数可以采用两种形式之一 - 它包含斜杠或不包含斜杠。

使用斜杠

execvp()参数指定可执行文件的路径名,可以是绝对名称(以斜杠开头)或相对名称(不是以斜杠开头,但包含斜杠)。 filepath函数不对参数进行任何更改,并且假定文件名称存在且可执行,则执行(或不执行)程序。

没有斜线

execvp()参数指定了一个“简单”名称,例如filepath。然后,ls函数尝试执行在excevp()环境变量中列出的某个目录中找到名为ls的程序。 $PATH中的p用于“路径”,与路径查找一样。

应用理论

如果用户将execvp()键入shell,通常的执行方法是创建一个等效于:

的字符指针数组
ls -a

char *argv[] = { "ls", "-a", 0 }; execvp(argv[0], argv); 现在将执行基于路径的分析,并尝试从execvp()中列出的某个目录执行ls

如果用户向shell键入$PATH,那么执行该方法的正常方法是创建一个等效于:

的字符指针数组
/bin/ls -a

char *argv[] = { "/bin/ls", "-a", 0 }; execvp(argv[0], argv); 现在将执行指定的绝对路径名,因为这是用户请求的内容(而不是execvp()/usr/bin/ls)。

请注意,处理实际上是相同的 - 您将命令行拆分为单词;每个单词都成为一个以空指针终止的字符指针数组的元素,并将第一个单词作为'filepath'参数传递给/usr/local/bin/ls,将整个数组作为第二个参数传递。

显然,shell可以缓存实际可执行文件的位置,而且很多shell都会这样做,因此execvp()不需要尝试查找程序(并且shell不会调用{{ 1}}但通常使用可执行文件的绝对路径名调用execvp()。但这不是必需的;它是一种优化。

请注意,没有什么可以阻止你这样做:

execvp()

现在execv()应该是char *argv[] = { "/honky/tonk/toys", "-a", 0 }; execvp("ls", argv); 而不是argv[0],因为它是运行的"/honky/tonk/toys"可执行文件。您在ls中找到的内容取决于您在系统上ls(例如,Mac OS X不支持它),但二进制文件的符号链接应该是指向/proc的链接。在Linux上,您很容易发现/proc报告二进制名称(/bin/ls),即使ps包含原始参数(因此ls/proc/PID/cmdline })。这是好还是取决于你的观点,但全世界都不是Linux。

答案 1 :(得分:1)

要在当前目录中运行/ bin / ls -a,您需要:

与C argv一样,main()NULL相同,除了argv[0]已终止,且路径与char* argv[] = { "/bin/ls", "-a", NULL }; execvp(argv[0], argv); 相同。

{{1}}