简体   繁体   English

为什么我的 C shell 没有输出任何东西?

[英]Why isn't my C shell outputting anything?

Working on a project for a class.处理 class 的项目。 We're supposed to write a C shell.我们应该写一个 C shell。 I've found a bunch of good examples, but for the life of me, I can't get my version to generate any output.我找到了一堆很好的例子,但对于我的生活,我无法让我的版本生成任何 output。

It keeps printing the prompt, but nothing else.它不断打印提示,但没有别的。

I've followed along with some examples near-verbatim trying to fix this, but still nothing.我已经跟随一些例子几乎逐字地试图解决这个问题,但仍然没有。

#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;

}

The output, regardless of what I do, is: output,不管我做什么,都是:

MyShell>
MyShell>
MyShell>

Can someone tell me where I went wrong?有人能告诉我哪里出错了吗?

parse() returns a pointer to the local array args . parse()返回一个指向本地数组args的指针。 Since the lifetime of args ends when parse() returns, any attempt to use the return value of parse() is undefined behavior.由于args的生命周期在parse()返回时结束,因此任何使用parse()的返回值的尝试都是未定义的行为。 You should allocate that array with malloc() instead (and free it later.).您应该使用malloc()分配该数组(并稍后释放它。)。

What happens in my test is that the compiler notices that the return value of parse() can't legally be used ( and it gives a warning!! which you should read and pay attention to!! ), so it just returns NULL instead.在我的测试中发生的是编译器注意到parse()的返回值不能合法使用(它会发出警告!!你应该阅读并注意!! ),所以它只返回NULL . When the child dereferences this pointer as *args to get the first argument for execvp , it segfaults and dies without calling execvp() .当孩子将此指针取消引用为*args以获取execvp的第一个参数时,它会出现段错误并在不调用execvp()的情况下死亡。 You could detect this if you checked the status returned by wait() , but you don't.如果您检查wait()返回的status ,您可以检测到这一点,但您没有。 So it just looks as if the child didn't do anything.所以看起来孩子什么也没做。

Oh, bonus bug: when end-of-file occurs on stdin (eg if you hit Ctrl-D), the string returned by fgets() will be empty and strIn[strlen(strIn)-1]='\0';哦,额外的错误:当stdin上出现文件结束时(例如,如果您按 Ctrl-D), fgets()返回的字符串将为空并且strIn[strlen(strIn)-1]='\0'; will store a null byte out of bounds.将存储超出范围的 null 字节。 You need to test the return value of fgets() .您需要测试fgets()的返回值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM