c - UNIX shell 段错误

标签 c shell unix segmentation-fault

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

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

我严重迷失了...我是 shell 新手,我不知道从这里该做什么。 我的代码给出了一个错误,指出段错误(核心转储)。任何和所有的帮助将不胜感激。

#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. 读取传入的命令,解析命令的各个部分
  2. fork 子进程 并执行每个命令而不使用 (< >>> |)
  3. 成功执行 每个命令都带有 <、>、>>
  4. 使用 | 成功执行每个命令

在转向#2 之前尝试先让#1 工作起来,正如之前提到的,使用函数会有很大帮助。我建议看看这篇文章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);
      }
   }
  }
}

关于c - UNIX shell 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21818435/

相关文章:

c - 线程参数打印垃圾值

c - fnmatch 与复杂模式 C 的用法

shell - 如何否定进程的返回值?

linux - 从另一个 bash 脚本中有选择地打开和关闭 bash 脚本

linux - cp -sr 和 ln -s 之间的符号链接(symbolic link)差异

bash - 根据列值组合制表符分隔的文件

字符串以 "-e"开头的 Shell 脚本

c - GNU 为 binutils、gcc 和 glib 配置选项

c - 为什么gdb甚至介入memcpy和其他系统函数?

javascript - 通过命令行管道生成的 javascript