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

基于C语言使用Fork执行文本文件中命令的程序问题排查

读取文件命令并通过fork执行的C程序问题排查

我想要编写一个C程序,读取文本文件中的命令并将其存入数组,再通过fork函数逐个执行这些命令,以下是我的部分代码和数据文件,需要帮助排查问题:

原代码

void Execfile(char*filename)
{
    char**T;
    int nb;
    FILE*f;
    char buff[MAX_ARG];
    f=fopen("data1.txt","rb");
     while(fgets(buff,MAX_ARG,f)!=NULL){
        T=File2TabArgv(filename,&nb);
    }
    fclose(f);
    execvp(T[0],T);
    printf("\n");
    printf("END");
}

数据文件(data1.txt)内容

sleep20

代码中的核心问题

  1. 文件名硬编码:函数参数filename未被使用,硬编码成固定的data1.txt,无法灵活指定输入文件。
  2. 命令解析逻辑错误:循环中每次调用File2TabArgv时传入的是文件名而非当前读取的行内容buff,相当于反复解析整个文件而非单条命令。
  3. 未使用fork创建子进程:直接调用execvp会替换当前进程,后续的printf("END")永远不会执行,也无法实现“逐个执行多个命令”的需求。
  4. 文件打开模式错误:用rb二进制模式读取文本文件,可能导致行尾处理异常,应使用r文本模式。
  5. 缺乏错误处理:未检查fopen是否成功,若文件不存在会直接崩溃。
  6. 命令格式错误:数据文件中的sleep20是无效命令,系统中不存在名为sleep20的程序,正确格式应为sleep 20。
  7. 内存泄漏风险:T每次循环被重新赋值,之前分配的内存未释放,会造成内存泄漏。

修正后的示例代码

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

#define MAX_ARG 256

// 简单实现命令字符串到argv数组的解析函数
char** File2TabArgv(char* cmd, int* arg_count) {
    char** argv = NULL;
    int count = 0;
    // 按空格和换行分割字符串
    char* token = strtok(cmd, " \n");
    
    while (token != NULL) {
        argv = realloc(argv, (count + 2) * sizeof(char*));
        argv[count++] = strdup(token);
        token = strtok(NULL, " \n");
    }
    if (argv != NULL) {
        argv[count] = NULL; // argv必须以NULL结尾
    }
    *arg_count = count;
    return argv;
}

void Execfile(char* filename) {
    // 以文本模式打开文件,检查是否成功
    FILE* f = fopen(filename, "r");
    if (f == NULL) {
        perror("打开文件失败");
        return;
    }
    
    char buff[MAX_ARG];
    while (fgets(buff, MAX_ARG, f) != NULL) {
        // 跳过空行
        if (strlen(buff) <= 1) continue;
        
        // 创建子进程执行命令
        pid_t pid = fork();
        if (pid == -1) {
            perror("创建子进程失败");
            continue;
        } else if (pid == 0) {
            // 子进程中解析命令并执行
            int arg_count;
            char** cmd_argv = File2TabArgv(buff, &arg_count);
            if (cmd_argv != NULL && cmd_argv[0] != NULL) {
                execvp(cmd_argv[0], cmd_argv);
                // 若execvp返回,说明执行失败
                perror("命令执行失败");
                // 释放解析时分配的内存
                for (int i = 0; i < arg_count; i++) {
                    free(cmd_argv[i]);
                }
                free(cmd_argv);
                exit(EXIT_FAILURE);
            }
            exit(EXIT_FAILURE);
        } else {
            // 父进程等待子进程执行完成,确保命令逐个执行
            waitpid(pid, NULL, 0);
        }
    }
    
    fclose(f);
    printf("END\n");
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        fprintf(stderr, "用法: %s <文件名>\n", argv[0]);
        return 1;
    }
    Execfile(argv[1]);
    return 0;
}

关键修改说明

  • 改用函数传入的filename参数打开文件,支持灵活指定输入文件。
  • 每次循环处理当前读取的行内容buff,解析为命令参数数组。
  • 通过fork创建子进程执行命令,父进程等待子进程完成后再处理下一条命令。
  • 添加了文件打开、进程创建、命令执行的错误处理,避免程序崩溃。
  • 修正了数据文件中的命令格式,需改为sleep 20才能正常执行。
  • 补充了内存释放逻辑,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:56:03