分段故障unix shell

时间:2014-02-16 23:47:40

标签: c shell unix segmentation-fault

我有一份学校作业,我必须创建一个可以执行以下操作的shell:

  1. 读取传入命令,解析命令的每个部分
  2. fork子进程并执行每个命令而不使用(<>>> |)
  3. 使用&lt ;,>,>>
  4. 成功执行每个命令
  5. 使用|
  6. 成功执行每个命令

    我很丢失......我是新手,我不知道从这里做什么。 我的代码给出了一个错误说明segmentation fault (core dumped)。任何和所有帮助将不胜感激。

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #define MAX_ARG 10
    
    int main()
    {
            char line [256];
            char prompt[] = "sh2 % ";
            char command[256], *args[MAX_ARG];
            int pid;
            char status;
            int i;
    
            /* spit out the prompt */
            printf("%s", prompt );
    
            while( fgets(line, sizeof line, stdin) != NULL)
            {
                    /* fgets leaves '\n' in input buffer. ditch it */
                    line [strlen(line)-1] = '\0';    
    
                    while (line !=  NULL)
                    {
                            //parse command and arg
                            args[0] = strtok(line, " "); //grab command
    
                            for (i=1; i<MAX_ARG; i++)       //grab arguments, to assume max = 10?
                            {
                                      //if a single command with arguments then set command & argument
    
                                    //for (i>0)
                                    {
                                            // check to see if the command is 'exit'
                                            if(!strcmp("exit", args[i]))
                                            {
                                                    exit(0);
                                            }
                                            {
                                                    int p[2];
                                                pipe(p)
    
                                                if (fork() == 0) //child
                                                {
                                                        close (0);
                                                        dup(p[0]);
                                                        exec("cmd2");
                                                }
                                                else
                                                {
                                                        close(1);
                                                        close(p[0]);
                                                        close(p[1]);
                                                        dup(p[1]);
                                                        exec("cmd1");
                                        }
                                                close(0);
                                                open("stdout.txt", "r");
                                                if (fork()== 0)
                                                {
                                                        exec("cmd3");
                                                }
                                        }
                                        else if (!strcmp(">", args[i]))
                                                open("stderr.txt". "w")
                                                if (fork() == 0)
                                                {
                                                        exec("cmd1");
                                                }
    
                                        }
                                        else if (!strcmp(">>", args[i]))
                                        {
                                                close(1);
                                                open("stdout_stderr.txt", "w");
                                                if (fork() == 0)
                                                {
                                                        close(2);
                                                        dup(1);
                                                        exec("cmd2");
                                                }
    
                                        }
                                        else
                                        {
                                                pid = fork();
    
                                                if (pid == 0)
                                                {
                                                        status = execvp(command,args);
                                                        exit(0);
                                                }
                                                else
                                                {
                                                        waitpid(-1);
                                                }
                                        }
                                }
                        }
                }
        }
        return 0;
    }
    

1 个答案:

答案 0 :(得分:0)

你的程序中有很多错误,所以很难指出一行并说出改变这一点。我认为你是想立刻做太多而不是建立坚实的基础。

在编程中,你想从小做起并以你的进步为基础,你的教授通过排列这些步骤帮你一个忙:

  1. 读取传入命令,解析命令的每个部分
  2. fork子进程 并在没有(&lt;&gt;&gt;&gt; |)
  3. 的情况下执行每个命令
  4. 成功执行 使用&lt ;,&gt ;,&gt;&gt;的每个命令
  5. 使用|
  6. 成功执行每个命令

    尝试将#1工作转移到#2并且如前所述使用函数将会有很大帮助。我建议看一下这篇文章http://bytes.com/topic/c/answers/215994-writing-shell-c,它会给你一个你可以建模的简单shell。这是一个基础解析器,可以帮助您开始#1(基于提到的帖子)

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char line[4096] = {0};
    char safeline[4096] = {0};
    int done = 0;
    int i = 0;
    char *s = line;
    char **t = NULL;
    char *prompt = ">";
    char *args = NULL;
    char *nl = NULL;
    int main(void)
    {
      while(!done)
      {
        printf("%s", prompt);
        fflush(stdout);
        if(NULL == fgets(line, sizeof line, stdin))
        {
          t = NULL;
          done = 1;
        }
        else
        {
          nl = strchr(line, '\n');
          if(nl != NULL)
          {
            *nl = '\0';
            strcpy(safeline, line);
          }
          else
          {
            int ch;
            printf("Line too long! Ignored.\n");
            while((ch = getchar()) != '\n' && ch != EOF)
            {
              continue;
            }
            if(ch == EOF)
            {
              done = 1;
            }
          }
          args = strchr(line, ' ');
          if(args != NULL)
          {
            *args++ = '\0';
          }
          if(!done)
          {
            printf("command -  %s :  args - %s\n",s, args);
          }
       }
      }
    }