3

我正在编写一个 UNIX shell,我必须使用execv()系统调用来创建一个进程。的参数之一execv()是可执行文件的文件路径。因此,如果有人输入/bin/ls,它将运行ls可执行文件。但我需要的是一个函数,当ls输入时,它将搜索ls(如which命令)的文件路径。有没有允许我这样做的功能?

不幸的是,这是一个学校项目,我不允许使用execvp()。我需要实现一些路径搜索功能,然后将该文件路径添加到execv()参数中。

4

9 回答 9

9

用于PATH = getenv("PATH")从环境中获取路径字符串,然后使用对strtok(PATH,":")thenstrtok(NULL,":")的连续调用将字符串中的路径解析PATH为 的数组char **path,您需要使用malloc(). 将path[x]++'/'放入argv[0]缓冲区,并用于access(buffer, X_OK)查看是否可以在该路径位置执行文件,如果可以,请执行execv(buffer,argv).

于 2008-09-29T13:33:05.507 回答
3

您需要 execvp(),它将搜索 PATH 变量中指定的路径,除非文件名包含“/”。

于 2008-09-29T00:20:33.883 回答
3

使用execvp.

char *args[] = {"ls", (char *) NULL};
execvp("ls", args);

例如,此示例将执行/bin/echo(假设/bin在您的 PATH 上)。

#include <unistd.h>

int main()
{
    char *args[] = {"echo", "hello world", (char *) NULL};
    execvp("echo", args);
    return 0;
}
于 2008-09-29T00:27:47.033 回答
3

如果您不能使用 execvp,您可以char** environ从 <unistd.h> 或char* getenv(const char* name)<stdlib.h> 获取 PATH 变量,然后用于int access(const char* filename, int mode)查看文件是否存在并且是否可执行。我将把实施留给你,因为这是一个学校项目。

于 2008-09-29T00:29:31.787 回答
2

我认为 execvp() 可以满足您的需要。

编辑:所以您实际上是在问如何手动执行此操作?在这种情况下...

  1. 在 envp 中找到你的 PATH(main() 的第三个参数)
  2. 将其拆分为单独的路径
  3. 使用 stat() 检查您的程序在每个程序中是否存在
  4. 执行你发现存在的第一个

或者,如果您想要一个真正可靠的实现,请使用this。不过,它可能会引发剽窃检测器:)

于 2008-09-29T00:18:50.347 回答
2

access()一些人建议您stat()在尝试使用execv(). 你不需要这样做。execv()如果无法执行请求的文件,将返回错误。

于 2008-09-30T00:38:40.807 回答
0

execvp:-)

编辑:好的。这是一个 Perl 版本,它可以作为您的问题的伪代码。

use List::Util qw(first);

my @path = split /:/, $ENV{PATH};
my $dir = first {$_ ||= '.'; -x "$_/$name"} @path
    or die "Can't find program $name\n";
exec "$dir/$name", @args;

split使用给定的分隔符将字符串拆分为字符串数组。first找到符合某个标准的第一个项目;在这里,目录和正在寻找的名称的连接是可执行的(-x)。然后它运行。

希望能帮助到你!

于 2008-09-29T00:20:14.227 回答
0

从 execvp 手册页:

   The  functions  execlp() and execvp() will duplicate the actions of the
   shell in searching for an executable file  if  the  specified  filename
   does  not  contain  a slash (/) character.  The search path is the path
   specified in the environment by the PATH variable.   If  this  variable
   isn’t specified, the default path ‘‘:/bin:/usr/bin’’ is used.  In addi-
   tion, certain errors are treated specially.

也许您可以使用 execlp()?如果必须使用 execv,则需要获取 PATH 环境变量的值,使用 strtok() 解析它以获取各个路径,将文件名附加到每个路径并尝试使用 execv() 执行它。

我会提供代码,但我不会为你做作业。

于 2008-09-29T00:26:15.010 回答
0

哦,学校项目...

好吧,如果您想要“类似哪个”的东西,为什么不直接执行“哪个”本身(Linux 上的 /usr/bin/which,而不是 bash 别名或 tcsh 内置)来获取您正在寻找的路径...

:-)

于 2008-09-29T17:13:52.480 回答