c - 我已经使用 C 程序实现了简单的 bash 像 shell,但它没有按预期工作

标签 c multiprocessing fork

我创建了一个类似 bash 的程序,但是当我尝试执行它时,它第一次工作正常,然后才没有按预期工作

重复显示最后执行的输出,而不是询问新的输入

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>
 #include<string.h>
 #include<sys/wait.h>

 char full_cmd[20];

 void command_source(char *cmd)
 {

    FILE *fp;
    char output[20];
    char *token;
    token = strtok(cmd," ");
    strcpy(full_cmd,"which ");
    strcat(full_cmd,token);
    fp = popen(full_cmd,"r");
    while (fgets(output, 20, fp) != NULL) {
            strcpy(full_cmd,output);
    }
    full_cmd[strlen(full_cmd)-1] = '\0';

    token = strtok(NULL," ");
    while (token != NULL)
    {
            strcat(full_cmd,token);
            token = strtok(NULL," ");
    }

  }

  void get_input(char input[10])
  { 
    printf("Enter the command:");
    scanf("%[^\n]s",input);
  }

  int launch_shell(char *buff[50],int status)
  {
    pid_t pid = fork();
    if( pid == 0 )
    {
            execv(buff[0],buff);
    }
    else if (pid > 0)
    {
            pid_t wpid = waitpid(pid, &status, 0);
    }
    else
            return 0;
    return 1;
  }

  int main()
  {
    char *buff[50];
    int status;
    char input[10];
    int count=0,ret=1;
    while(ret == 1)
    {
            get_input(input);
            command_source(input);
            strcpy(buff[0],full_cmd);
            buff[1] = NULL;
            int ret = launch_shell(buff,status);
    }
  }

预期:

Enter the command:ls 
server.c server
Enter the command:ls -l
server.c
server

实际结果:

Enter the command:ls
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
server  server.c
...

请大家帮我看看这个问题。我花了一整天的时间来解决这个问题。但我做不到。

最佳答案

随着声明

scanf("%[^\n]s",input);

你的意思是“阅读直到出现换行符”。因此,在第一次输入后,换行符会保留在输入流中,从而防止立即停止后续输入读取。更好的主意是使用 fgets() 而不是 scanf()

您可以将大小参数传递给 get_input 函数,例如:

  void get_input(char input[10], size_t size)
  { 
    printf("Enter the command:");
    if (fgets(input, size, stdin) != NULL) {
        char *p = strchr(input, '\n');
        if (p) *p = '\0';
    } else {
        fprintf(stderr, "fgets failed\n");
        exit(1);
    }
  }

并调用它:

    get_input(input, sizeof input);

您还存在一些问题:

1.

strcpy(buff[0],full_cmd);

不正确,因为 buff[0] 未初始化。您可以只分配:

buff[0] = full_cmd;
  • 在当前方法中,您不能使用命令参数。因为每个参数和命令都需要作为数组buff的不同参数传递给execv

    因此,在调用launch_shell之前,需要根据空格分割输入并将其放入数组buff中。例如,“ls -l”将是 execv 的单个参数(通过 buff[0] 传递)。但这不是 execv 接受的。您需要将“ls”放入 buff[0] 中,将“-l”放入 buff[1] 中,将 NULL 放入 buff[2] 中然后调用execv

  • 关于c - 我已经使用 C 程序实现了简单的 bash 像 shell,但它没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54098209/

    相关文章:

    c - 在 union 中写入字节数组并从 int 读取以转换 MISRA C 中的值是否合法?

    python - 获取 TypeError : can't pickle _thread. 锁定对象

    python - 如何在 Python 中配置 `/dev/shm/` 或 `_multiprocessing.SemLock` 的替代方案

    c - 理解这些过程如何运作的问题

    c - fork() c 中的两个子进程

    c - Linux中的进程fork

    c++ - 当您只能使用 C 文件时,为什么要创建新的头文件?

    c - 用于声明可能与结构中的变量或成员匹配的元变量的正确类型是什么?

    c - 想在 C 中创建一个写模式的文件

    Python 多处理管道不会正确接收 ()