execvp 文件路径说明

Pet*_*ppy 1 c execvp

我正在用 C 编写一个 shell,但我无法理解execvp(filepath,argv).

如果输入的用户想要ls -a在他们当前的目录中运行......让我们说/home/user1......在所述目录中运行的filepathandargvls什么?

请问filepath是哪里的命令将被执行的目录/home/user1或者这将是命令的位置/bin/ls

Jon*_*ler 5

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

带斜线

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

没有斜线

filepath参数指定一个“简单”的名称,如lsexcevp()然后,该函数试图执行一个程序,该程序的名称ls$PATH环境变量中列出的目录之一中找到。该pexecvp()是“路径”,在路径查找。

应用理论

如果用户键入ls -ashell,执行该命令的正常方法是创建一个字符指针数组,等效于:

char *argv[] = { "ls", "-a", 0 };

execvp(argv[0], argv);
Run Code Online (Sandbox Code Playgroud)

现在execvp()将进行基于路径的分析,并尝试ls从 中列出的目录之一执行$PATH

如果用户键入/bin/ls -ashell,则执行该操作的正常方法是创建一个等效于以下内容的字符指针数组:

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

execvp(argv[0], argv);
Run Code Online (Sandbox Code Playgroud)

现在execvp()将执行指定的绝对路径名,因为这是用户请求的(而不是说,/usr/bin/ls/usr/local/bin/ls)。

请注意,处理实际上是相同的——您将命令行拆分为单词;每个单词都成为以空指针结尾的字符指针数组的一个元素,您将第一个单词execvp()作为 'filepath' 参数传递给,并将整个数组作为第二个参数传递。

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

还要注意,没有什么可以阻止你做:

char *argv[] = { "/honky/tonk/toys", "-a", 0 };
execvp("ls", argv);
Run Code Online (Sandbox Code Playgroud)

现在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。