C/C++编写Shell调用chdir切换目录后出现卡顿与命令执行报错问题
问题根因分析
- 逻辑顺序错误:fork操作放在了内置命令cd的判断之前,每次输入cd命令都会额外创建一个子进程,子进程没有正常退出,会和父进程同时抢占终端输入,导致输入内容被拆分、程序卡顿、命令执行报错只显示部分字符。
- cd命令判断逻辑错误:readline返回的输入字符串默认不带末尾换行符,你使用
strncmp(command[0], "cd\n", 2)做判断,仅匹配前2个字符会导致所有以cd开头的字符串都被误识别为cd命令,且不需要匹配换行符。 - 资源泄漏:cd分支执行continue跳转下一轮循环前,没有释放
input和command的堆内存,长期运行会导致内存泄漏。 - 子进程退出逻辑缺失:execvp执行失败后子进程没有主动退出,会继续进入主循环抢占终端输入。
- cd参数边界缺失:未处理用户仅输入
cd不带参数的场景,直接访问command[1]会触发空指针访问段错误。 - 头文件缺失:代码使用了strtok、strcmp等C字符串处理函数,但未引入<string.h>头文件,部分编译器下会出现隐式声明报错。
修复方案
调整代码逻辑顺序,先处理内置命令再处理外部命令,修正判断条件和退出逻辑,修复后的完整代码如下:
#include <stdio.h> #include <readline/readline.h> #include <sys/wait.h> #include <unistd.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> #include <string> #define clear() printf("\033[H\033[J") char** getInput(char* input) { char** command = (char**) malloc(8 * sizeof(char*)); const char* separator = " "; char* parsed; int index = 0; parsed = strtok(input, separator); while (parsed != NULL) { command[index] = parsed; index++; parsed = strtok(NULL, separator); } command[index] = NULL; return command; } int main() { char** command; char* input; pid_t child_pid; int stat_loc; bool loop = true; do { input = readline(""); // 空输入直接跳过 if (!input || !*input) { free(input); continue; } command = getInput(input); // 先处理内置命令cd,不需要fork if (strcmp(command[0], "cd") == 0) { const char* target_dir = command[1]; // 不带参数默认切换到HOME目录 if (!target_dir) { target_dir = getenv("HOME"); } if (chdir(target_dir) < 0) { printf("Couldn't execute cd to: %s\n", target_dir); } // 处理完释放资源 free(input); free(command); continue; } // 外部命令才fork执行 child_pid = fork(); if (child_pid < 0) { printf("Fork Failed\n"); free(input); free(command); exit(EXIT_FAILURE); } if (child_pid == 0) { execvp(command[0], command); printf("couldn't execute: %s\n", command[0]); // 子进程执行失败必须退出,避免继续跑主逻辑 exit(EXIT_FAILURE); } else { waitpid(child_pid, &stat_loc, WUNTRACED); } free(input); free(command); } while (loop); return 0; }
编译指令保持不变:g++ main.cc -lreadline
内容的提问来源于stack exchange,提问作者Anirudh Yamunan Govindarajan
相关产品推荐
相关产品推荐

