C - execvp 文件路径说明



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

如果键入的用户想要在其当前目录中运行ls -a...比方说/home/user1...在所述目录中运行lsfilepathargv是什么?

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

execvp()filepath参数可以采用两种形式之一 - 它包含斜杠或不包含斜杠。

带斜杠

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

不带斜杠

filepath参数指定一个"简单"名称,例如 ls 。 然后,excevp()函数寻求执行名称ls$PATH环境变量中列出的目录之一中找到的程序。 execvp()中的p用于"路径",就像在路径查找中一样。

应用理论

如果用户键入 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(。

请注意,处理实际上是相同的 — 您将命令行拆分为单词;每个单词都成为字符指针数组的一个元素,该数组以 null 指针结尾,您将第一个单词作为 '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 OS X 不支持它(,但指向二进制文件的符号链接应该是指向/bin/ls的链接。 在 Linux 上,你很容易发现 ps 报告二进制名称 ( ls (,即使/proc/PID/cmdline包含原始参数(所以argv[0]/honky/tonk/toys(。 这是否好取决于你的观点,但全世界都不是Linux。

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

与 C 程序启动时传递到 main() argv相同,但NULL终止,路径与 argv[0] 相同。

char* argv[] = { "/bin/ls", "-a", NULL };
execvp(argv[0], argv);

最新更新