You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言自制迷你shell execvp执行报错问题如何修复

迷你Shell代码问题排查与修复方案

核心问题列表

  • 野指针访问:username 仅声明为字符指针未分配内存,scanf 直接向非法地址写入数据,会触发段错误。
  • 输入缓冲区残留换行:scanf 读取用户名后,用户输入的换行符残留在标准输入缓冲区,第一次执行 fgets 会直接读到空字符串,导致首次命令执行异常。
  • 命令携带换行符:fgets 会将用户输入的换行符一并存入命令数组,分词后命令/参数末尾会携带\n字符,execvp 无法匹配到对应可执行文件。
  • 数组越界风险:argv 数组仅定义了3个元素的空间,当命令参数超过2个时会触发数组越界,内存被篡改导致execvp执行失败。
  • 分词规则不全:仅以空格作为分词分隔符,无法处理制表符、换行等其他空白字符的分割场景。

修复步骤

  1. 将username改为定长字符数组,分配足够的存储空间避免野指针:char username[256];
  2. scanf读取用户名后调用getchar(),吃掉缓冲区残留的换行符。
  3. fgets读取命令后,手动移除末尾的换行符:comand[strcspn(comand, "\n")] = '\0';
  4. 放大argv数组长度,改为char *argv[64];,支持最多63个命令参数。
  5. 调整strtok的分隔符为" \t\n",兼容多种空白字符分割场景。

修复后完整代码

#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_LINE 1024

void run_shell(char * cmd){
        char * str = cmd;
        char delims[] = " \t\n";

        char * token = strtok(str, delims);
        char * argv[64];
        int i = 0;
        while(token != NULL){
                argv[i] = token;
                i++;
                token = strtok(NULL, delims);
        }

        argv[i] = NULL;

        pid_t pid;

        if((pid = fork()) == 0){
                if(execvp(argv[0], argv) < 0){
                        perror("Invalid Command");
                        exit(EXIT_FAILURE);
                }
        }
        else{
                if(waitpid(pid, NULL, 0) < 0){
                        perror("Wait Process Error");
                        exit(EXIT_FAILURE);
                }
        }
        printf("\n");
}

int main(){
        char comand[MAX_LINE];
        char username[256];

        printf("Enter your name : ");
        scanf("%s", username);
        getchar();

        while(1){
                char cwd[MAX_LINE];
                getcwd(cwd, sizeof(cwd));

                printf("%s %s$ > ", username, cwd);

                fgets(comand, MAX_LINE, stdin);
                comand[strcspn(comand, "\n")] = '\0';

                printf("\n");
                run_shell(comand);
        }
}

内容的提问来源于stack exchange,提问作者김정훈

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:06:05