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

C语言读取文件执行Shell脚本时出现无限循环问题排查

问题分析与修复方案

当运行包含3行及以上命令的脚本时,shell陷入无限循环,核心问题出在内存泄漏引发堆损坏,以及未正确处理内置命令exit,具体分析和修复如下:

问题1:内存泄漏导致堆损坏

在myShellScript函数中,args指针每次循环都会被wish_split_line重新赋值,但只有最后一次分配的内存被free,前面所有循环产生的内存都发生泄漏。当泄漏积累到一定程度时,会破坏堆内存结构,导致文件指针fptr或fgets的行为异常,无法正确检测到文件末尾,从而进入无限循环。

修复代码

修改myShellScript的循环逻辑,每次执行完命令后立即释放args:

// When myShell is called with a Script as Argument
int myShellScript(char filename[100])
{
//    printf("Received Script. Opening %s", filename);
    FILE *fptr;
    char line[200];
    char **args;
    fptr = fopen(filename, "r");
    if (fptr == NULL)
    {
        printf("\nUnable to open file.");
        return 1;
    }
    else
    {

//        printf("\nFile Opened. Parsing. Parsed commands displayed first.");
        while(fgets(line, sizeof(line), fptr)!= NULL)
        {
            args= wish_split_line(line);
            wish_execute(args);
            free(args); // 每次循环后释放args,避免内存泄漏
        }
    }
    fclose(fptr); // 移除循环外的free(args),内存已在循环内释放
    return 1;
}

问题2:exit命令未正确终止脚本

如果wish_execute未将exit作为内置命令处理,而是当作外部命令执行,子进程执行exit只会终止自身,父进程会继续循环读取脚本内容。即使脚本到末尾,内存损坏也可能导致循环无法终止。

修复方案

修改wish_execute函数,将exit作为内置命令处理:

  • 检测到args[0]为"exit"时,返回特殊值(如0)
  • 在myShellScript中根据返回值跳出循环:
// 修改myShellScript的循环部分
while(fgets(line, sizeof(line), fptr)!= NULL)
{
    args= wish_split_line(line);
    int exec_ret = wish_execute(args);
    free(args);
    if (exec_ret == 0) { // 触发exit命令,终止脚本循环
        break;
    }
}

// 在wish_execute中添加exit处理逻辑(示例)
int wish_execute(char **args)
{
    if (args[0] == NULL) {
        return 1;
    }
    if (strcmp(args[0], "exit") == 0) {
        return 0; // 返回0告知调用者终止循环
    }
    // 处理其他内置命令...
    // 执行外部命令
    return wish_launch(args);
}

额外检查点

  • 确认wish_split_line返回的args数组以NULL结尾,避免execvp执行出错
  • 检查p1.sh等外部脚本是否存在修改父进程脚本文件的操作(如追加内容),这也可能导致脚本被无限读取

内容的提问来源于stack exchange,提问作者Oreofe Solarin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:50:25