实现支持多管道命令的简易Shell出现阻塞及tr命令兼容问题求助
简易Shell管道阻塞与tr命令兼容问题求助
我编写了一段C语言代码,试图实现一个支持多管道命令的简易Shell。该Shell执行单条命令时功能正常,但执行带管道的命令时会出现阻塞情况。调试时无法命中断点子进程内的断点,怀疑是管道关闭逻辑存在问题,但不确定具体原因,耗时数小时仍未解决。另外发现该Shell也无法正常兼容tr命令。
以下是相关代码:
void executefork(char **commands, int num_commands, int input_fd) { if (num_commands == 0) { return; } int pipefd[2]; if (pipe(pipefd) == -1) { perror("pipe"); return; } pid_t pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { if (num_commands > 1) { if (dup2(pipefd[1], STDOUT_FILENO) == -1) { perror("dup2"); exit(EXIT_FAILURE); } } if (input_fd != STDIN_FILENO) { if (dup2(input_fd, STDIN_FILENO) == -1) { perror("dup2"); exit(EXIT_FAILURE); } } close(pipefd[0]); close(pipefd[1]); execute(commands[0]); } else { close(pipefd[1]); if (num_commands > 1) { printf("\nReached"); executefork(commands + 1, num_commands - 1, pipefd[0]); } close(pipefd[0]); int status; if (waitpid(pid, &status, 0) == -1) { perror("waitpid"); exit(EXIT_FAILURE); } } } int main(int argc, char *argv[]) { size_t len = 1024; ssize_t cha; char *line = (char *) malloc(len); char *pipeCmd[strlen(line)]; while (1) { printf("sish> "); cha = getline(&line, &len, stdin); if (cha == -1 || cha == 0) { continue; } line[strcspn(line, "\n")] = '\0'; if (line[0] == '\0') { continue; } char *copy = strdup(line); char *com = strtok(copy, "|"); int index = 0; while (com != NULL) { pipeCmd[index++] = com; addHistory(com); com = strtok(NULL, "|"); } pipeCmd[index] = NULL; executefork(pipeCmd, index, STDIN_FILENO); if (flag == 1) { break; } } free(line); return 0; } void execute(char *phrase) { char *va = strdup(phrase); char *token = strtok(strdup(va), " "); if (strcmp(token, "history") == 0) { history(phrase); return; } else if (strcmp(token, "exit") == 0) { flag = 1; return; } else if (strcmp(token, "cd") == 0) { changeDir(phrase); return; } else { pid_t cpid; cpid = fork(); if (cpid < 0) { perror("fork error"); exit(-1); } if (cpid == 0) { char *pass[sizeof(phrase) / sizeof(char *) + 1]; int i = 0; while (token != NULL && i < sizeof(pass) / sizeof(char*)) { pass[i++] = token; token = strtok(NULL, " "); } pass[i] = NULL; execvp(pass[0], pass); perror("execvp failed"); exit(EXIT_FAILURE); } else { waitpid(cpid, NULL, 0); } } }
测试案例1:管道命令阻塞
sish> cat pi.txt //此部分正常 Hello people, Run debug save share stop download languages sish> cat pi.txt | grep the //此命令持续阻塞
测试案例2:tr命令兼容问题
sish> echo "Hi how are you" | tr h w tr: missing operand after ‘h’ Two strings must be given when translating. Try 'tr --help' for more information. waitpid: No child processes
内容的提问来源于stack exchange,提问作者Pranjal
相关产品推荐
相关产品推荐

