为什么我的 C shell 不输出任何内容?

问题描述

一个班级做一个项目。我们应该写一个C shell。我找到了很多很好的例子,但在我的一生中,我无法让我的版本生成任何输出

它一直打印提示,但没有其他内容

我已经跟随着一些几乎逐字逐句的例子试图解决这个问题,但仍然没有。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <stdbool.h>

#include <sys/wait.h>



/******************************************

  @brief Fork a child to execute the command using execvp. The parent should wait for the child to terminate

  @param args Null terminated list of arguments (including program).

  @return returns 1,to continue execution and 0 to terminate the MyShell prompt.

******************************************/

int execute(char **args)

{

    pid_t  pid;
        int status;

        if ((pid = fork()) < 0) 
        {     
              printf("*** ERROR: forking child process Failed\n");
              exit(1);
        }
        else if (pid == 0) 
        {          
          if (execvp(*args,args) < 0) {     
               printf("*** ERROR: exec Failed\n");
               exit(1);
          }
        }
        else 
        {                                  
          while (wait(&status) != pid)       
               ;
        }
        
        return 0;

}





/******************************************

  @brief gets the input from the prompt and splits it into tokens. Prepares the arguments for execvp

  @return returns char** args to be used by execvp

******************************************/

char** parse(void)

{

    //Get the string and store it. Remove newline.  

    char strIn[255];

    printf("MyShell>");

    fgets(strIn,sizeof(strIn),stdin); 

    strIn[strlen(strIn)-1]='\0';

    

    //Array,token,counters. 

    char *args[20]; 

    char *tok; 

    int i = 0;

    int count = 0;

    

    //Allocate array. 

    for(i = 0; i < 20; i++)

    {

        args[i] = (char*)malloc(20 * sizeof(char));

    }

    

    //Fill in args[0]

    tok = strtok(strIn," ");

    strcpy(args[count++],tok);

    

    //Fill in array with tokens. 

    while (tok != NULL)

    {

        tok = strtok(NULL," ");

        

        if (tok == NULL)

            break;

            

        strcpy(args[count++],tok);

    }

    

    //Null terminate.

    args[count] = NULL;

        

    return args; 

}





/******************************************

   @brief Main function should run infinitely until terminated manually using CTRL+C or typing in the exit command

   It should call the parse() and execute() functions

   @param argc Argument count.

   @param argv Argument vector.

   @return status code

******************************************/

int main(int argc,char **argv)

{

    bool run = true; 

    

    while(run)

    {

        char** argArr = parse(); 

        execute(argArr);


        }

        

    return 0;

}

无论我做什么,输出都是:

MyShell>
MyShell>
MyShell>

谁能告诉我哪里出错了?

解决方法

parse() 返回指向本地数组 args 的指针。由于 args 的生命周期在 parse() 返回时结束,因此任何使用 parse() 返回值的尝试都是未定义行为。您应该改为使用 malloc() 分配该数组(并稍后释放它!)。

在我的测试中发生的情况是编译器注意到 parse() 的返回值不能合法使用 (and it gives a warning!! which you should read and pay attention to!!),因此它只返回 NULL。当子节点将此指针取消引用为 *args 以获取 execvp 的第一个参数时,它会出现段错误并死亡,而不会调用 execvp()。如果您检查 status 返回的 wait(),您可以检测到这一点,但您没有。所以看起来好像孩子什么都没做。

哦,额外的错误:当文件结束出现在 stdin 上时(例如,如果您按 Ctrl-D),fgets() 返回的字符串将为空,而 strIn[strlen(strIn)-1]='\0'; 将越界存储空字节。您需要测试 fgets() 的返回值。