使用execv()时没有这样的文件或目录

Tim*_*giz 1 c shell execv

我试着写一个基本的shell,可以解释简单的命令,比如语言c中的date,ls.

我首先获取这样的PATH变量,然后将其传递给execv()函数.

const char *name = "PATH";
char *value;
value = getenv(name)
Run Code Online (Sandbox Code Playgroud)

我打印出价值,我得到了这个:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Run Code Online (Sandbox Code Playgroud)

请注意,我使用virutalbox来运行Ubuntu.这是我用来尝试简单的ls命令的代码.在下面的代码中,变量行是用户编写的实际命令,在我们的例子中它是"ls"

  pid_t pid, wpid;
  int status;

  pid = fork();
  if (pid == 0) {
      // Child process
      if (execv(value, line) == -1) {
          perror("lsh");
      }
      exit(EXIT_FAILURE);
  }
  else if (pid < 0) {
        // Error forking
        perror("lsh");
  }
  else {
      // Parent process
      do {
          wpid = waitpid(pid, &status, WUNTRACED);
      }
      while (!WIFEXITED(status) && !WIFSIGNALED(status));
    }
Run Code Online (Sandbox Code Playgroud)

我得到的结果是这样的:

lsh: no such file or directory
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Jon*_*ler 5

execv()系统调用使用你的第一个参数为可执行文件的文件名指定的名称; 它不会进行基于PATH的搜索.

这意味着如果指定"lsh"为第一个参数,则lsh当前目录中必须存在可执行文件.

如果您想要基于PATH的搜索,请替换execv()execvp().否则,在第一个参数中指定命令的路径名 - 绝对或相对,但绝对更正常.

请注意,如果任何exec*()函数返回,则表示失败.没有必要测试返回值; 它总是-1.

内容valueline需要遵循:

char *value = "ls";
char *line[] = { "ls", "-l", 0 };

execvp(value, line);
Run Code Online (Sandbox Code Playgroud)

或者,更常规地:

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

如果您自己分析PATH,则需要line[0]指向从PATH创建的完整文件名,然后使用execv()而不是execvp().