execvp() ls 没有这样的文件或目录

execvp() ls no such file or directory

我正在编写一个 shell 模拟器,如果用户输入 "lsh ls" 我会 运行 命令 ls 并忽略输入的 "lsh"由用户。所以我正在使用 readline 库来获取输入,然后解析该行。然后我使用 fork() 和 execvp() 来 运行 ls 命令。但是,当我键入 lsh ls 时,我得到以下输出:

lsh: ls: No such file or directory

这是我的代码。我认为它将 ls 视为要搜索的文件,但我不明白为什么要这样做。

int main(){
  pid_t id;
  char* line;
  char **args;
  while(1){
    line = readline("shell: > ");
    if(strcmp(line,"exit") == 0){
        break;
    }
    args = parse(line);
    if(strcmp(args[0],"lsh") == 0){
        id = fork();
        if (id == 0){
            if(execvp(args[1],args) < 0){
                perro("no such command");
            }
        }
        if(id > 0){
            printf("I am the parent process, id %d\n",getppid());
        }
    }   
    free(line);
  }
}

这是解析行的函数。

#define LSH_TOK_BUFSIZE 64
#define LSH_TOK_DELIM " \t\r\n\a"
char **parse(char *line){
   int bufsize = LSH_TOK_BUFSIZE, position = 0;
   char **tokens = malloc(bufsize * sizeof(char*));
   char *token;
   if (!tokens) {
    fprintf(stderr, "lsh: allocation error\n");
        exit(EXIT_FAILURE);
   }

  token = strtok(line, " \n");
  while (token != NULL) {
    tokens[position] = token;
    position++;

  if (position >= bufsize) {
    bufsize += LSH_TOK_BUFSIZE;
    tokens = realloc(tokens, bufsize * sizeof(char*));
  if (!tokens) {
    fprintf(stderr, "lsh: allocation error\n");
    exit(EXIT_FAILURE);
  }
  }

  token = strtok(NULL, LSH_TOK_DELIM);
  }
  tokens[position] = NULL;
  return tokens;
  free(tokens);
}

您看到的错误消息来自 ls,而不是 lsh

你实际上有:

char *args[] = { "lsh", "ls", 0 };

execvp(args[1], args);

这意味着您尝试执行 ls,并且执行成功,但是您告诉 ls 它被称为 lsh,因为 argv[0] 被设置为 lsh 并请求它列出当前目录中的文件 ls。因此,当 ls 尝试查找文件时,它失败了,并使用您给它的命令名称 lsh.

报告错误

你可以试试这个(显示的输出是在 macOS Sierra 上获得的):

$ cp /bin/ls xx97
$ ./xx97 23-ish
xx97: 23-ish: No such file or directory
$ rm xx97

您需要使用:

execvp(argv[1], &argv[1]);

然后你将以正统的方式调用ls