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

时间:2016-10-02 15:58:17

标签: c shell ls

我正在编写一个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);
}

1 个答案:

答案 0 :(得分:3)

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

你实际上已经:

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

execvp(args[1], args);

这意味着您尝试执行ls并成功执行此操作,但是您告诉ls它被称为lsh,因为argv[0]设置为{{1}并请求它列出当前目录中的文件lsh。因此,当ls尝试查找文件时,它会失败,并使用您提供的命令名ls报告错误。

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

lsh

您需要使用:

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

然后你以正统的方式调用execvp(argv[1], &argv[1]);