麻烦大佬们帮我看看为什么我的这段shell程序如果直接回车会报错啊
程序代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <sys/types.h> #include <readline/readline.h> #include <readline/history.h> pid_t pid; int bg = 0;//是否后台运行 char commands[256][256];//分割后的命令 int inNum, outNum;//是否有重定向输出输入 int pipe_command(int, int); //父进程处理信号函数 void signalCat() { if (pid != 0) { kill(pid, SIGINT); int status; waitpid(pid, &status, 0); } } //分割命令并返回条数 int split(char *command) { int num = 0; int i, j; int len = strlen(command); for (i = 0, j = 0; i < len; i++) { if (command[i] != ' ') { commands[num][j++] = command[i]; } else { if (j != 0) { commands[num][j] = '\0'; num++; j = 0; } } } if (j != 0) { commands[num][j] = '\0'; num++; } return num; } //执行函数 int redo_command(int l, int r) { char *inFile = NULL, *outFile = NULL; int in_h = r, out_h = r, flag = 0; //寻找重定向 for (int i = l; i < r; i++) { if (strcmp(commands[i], "<") == 0) { inNum++; if (i + 1 < r) { inFile = commands[i + 1]; } else { perror("in have no parameter\n"); return -1; //重定向符号后缺少文件名 } in_h = i; } if (strcmp(commands[i], ">") == 0 || strcmp(commands[i], ">>") == 0) { outNum++; if (i + 1 < r) { outFile = commands[i + 1]; } else { perror("out have no parameter\n"); return -1; //重定向符号后缺少文件名 } out_h = i; if (strcmp(commands[i], ">>")==0) flag = 1; } } //如果多个重定向,错误 if (inNum > 1 || outNum > 1) { perror("have too much in and out\n"); return -1; } //分段递归执行 int max_h = in_h; if (in_h < out_h) max_h = out_h; int result = 0; pid = fork(); int min_h = in_h; if (in_h > out_h) min_h = out_h; if (inNum == 1) freopen(inFile, "r", stdin); if (outNum == 1) { if (flag == 0) freopen(outFile, "w", stdout); else freopen(outFile, "a", stdout); } if (pid < 0) { perror("creat process fail\n"); result = -1; } else if (pid == 0) { char *comm[256]; int tag = 0; for (int i = l; i < min_h; i++) comm[tag++] = commands[i]; comm[tag] = NULL; execvp(comm[0], comm); perror("input error!\n"); exit(EXIT_FAILURE); } else { if (abs(in_h - out_h) > 2) { pipe_command(min_h + 2, max_h); } if (max_h + 1 < r) pipe_command(max_h + 2, r); int status; if (bg == 0) { waitpid(pid, &status, 0); } else { printf("BACKGROUND RUNNING\n"); } } return result; } //是否有管道,有管道就相当于父子进程间的通信 int pipe_command(int l, int r) { if (l >= r) return 0; int pipe_h = -1; //判断是否有管道命令 for (int i = l; i < r; i++) { if (strcmp(commands[i], "|") == 0) { pipe_h = i; break; } } if (pipe_h == -1) { //无管道命令 return redo_command(l, r); } else if (pipe_h + 1 == r) { //管道命令'|'后没有指令,也就是没有参数 printf("| have no parameter\n"); return -1; } //开始执行命令 int pipe_id[2]; if (pipe(pipe_id) < 0) { perror("create pipe error\n"); return -1; } int result = 0; pid = fork(); if (pid == -1) { result = -1; } else if (pid == 0) {//子进程执行单个命令 close(pipe_id[0]); dup2(pipe_id[1], STDOUT_FILENO); //将标准输出重定向到pipe_id[1] result = redo_command(l, pipe_h); exit(result); } else { // 父进程递归执行后续命令 int status; waitpid(pid, &status, 0); if (pipe_h + 1 < r) { close(pipe_id[1]); dup2(pipe_id[0], STDIN_FILENO); result = pipe_command(pipe_h + 1, r); } } return result; } int main() { signal(SIGINT, signalCat); read_history(NULL); while (1) { inNum = 0; outNum = 0; char *argv; argv = readline("Myshell$ "); add_history(argv); int len = strlen(argv); if (strcmp(argv, "exit") == 0) { printf("thanks for your use!\n"); exit(EXIT_SUCCESS); } if (argv[len - 1] == '&') {//是否后台 bg = 1; argv[len - 1] = '\0'; } else bg = 0; int commandNum = split(argv); // for (int i = 0; i < commandNum; i++) { // printf("%s\n", commands[i]); // } // 获取标准输入、输出的文件标识符 int inPipe = dup(STDIN_FILENO); int outPipe = dup(STDOUT_FILENO); pipe_command(0, commandNum); //还原标准输入、输出重定向 dup2(inPipe, STDIN_FILENO); dup2(outPipe, STDOUT_FILENO); free(argv); } return 0; }