execvp无输出问题:自制Shell执行命令失效排查
问题分析与修复方案
核心问题排查
你的代码存在两个关键问题,导致ls等命令无法正常输出:
- 换行符未清理:
fgets读取输入时会将换行符\n一并存入缓冲区,比如输入ls后,cmd实际内容是"ls\n"。execvp会尝试执行名为ls\n的命令,系统中不存在该命令,直接执行失败。 - execvp参数格式错误:
execvp的第二个参数要求是以NULL结尾的字符串数组,你传入的&commandarray是单个字符串的地址,不符合API要求,导致命令解析失败。
修复后的代码
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <errno.h> #include <string.h> int executecommand(char *args[]) { pid_t pid = fork(); if (pid < 0) { perror("fork failed"); return errno; } else if (pid == 0) { execvp(args[0], args); // 走到这里说明execvp执行失败 perror("execvp failed"); _exit(1); // 子进程必须退出,避免执行父进程逻辑 } else { int waitstatus; waitpid(pid, &waitstatus, 0); return 0; } } int waitforinput() { printf("$ "); char cmd[256]; if (fgets(cmd, 256, stdin) == NULL) { return 1; // 处理输入结束或读取错误 } // 移除换行符 cmd[strcspn(cmd, "\n")] = '\0'; // 构造符合execvp要求的参数数组(仅支持无参数命令,如需参数需扩展拆分逻辑) char *args[2]; args[0] = cmd; args[1] = NULL; // 必须以NULL结尾 executecommand(args); return 0; } int main(int argc, char **argv) { waitforinput(); return 0; }
关键修改说明
- 清理换行符:用
strcspn定位换行符位置,替换为字符串结束符\0,确保命令名正确。 - 修正参数格式:创建以NULL结尾的参数数组,严格符合
execvp的API要求。 - 子进程错误处理:
execvp返回时打印错误并调用_exit退出子进程,避免干扰父进程逻辑。
内容的提问来源于stack exchange,提问作者Jocomol
相关产品推荐
相关产品推荐

