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

如何解决execv执行后未指定重定向仍持续写入文件的问题

问题修复方案

问题根源

当前代码的核心问题是全局变量INSERT_PATH仅在子进程中被重置,但子进程拥有独立的地址空间,修改不会同步到父进程。导致父进程中INSERT_PATH始终保留着上一次的重定向路径,后续未指定重定向的命令依然会触发文件写入逻辑。此外,文件打开模式不符合Shell的>重定向行为(默认应覆盖而非追加),且缺乏必要的错误处理。

修改步骤与代码实现

1. 修正write_file_if_exists函数

  • 调整文件打开模式为O_WRONLY | O_CREAT | O_TRUNC,实现覆盖式写入,符合标准重定向语义
  • 增加open和dup2的错误处理,避免异常情况导致程序崩溃
  • 移除无用的data参数(原代码未使用)
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

void write_file_if_exists(char *path) {
    // 打开目标文件:只写模式,不存在则创建,存在则截断清空
    int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("Failed to open output file");
        exit(EXIT_FAILURE);
    }

    // 将标准输出重定向到文件
    if (dup2(fd, STDOUT_FILENO) == -1) {
        perror("Failed to redirect stdout");
        close(fd);
        exit(EXIT_FAILURE);
    }

    close(fd);
}

2. 修正run_bin函数

  • 将INSERT_PATH的重置操作移至父进程,确保每次命令执行完成后清理状态
  • 增加fork和execv的错误处理
  • 子进程在execv失败后直接退出,避免执行父进程后续代码
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 假设INSERT_PATH是全局定义的字符指针数组
extern char *INSERT_PATH[];

char** commands(const char* command_line); // 原命令解析函数

int run_bin(const char* command_line){
    char **commands_list = commands(command_line);
    if (!commands_list || !commands_list[0]) {
        fprintf(stderr, "Invalid command\n");
        return -1;
    }

    char bin[20] = "/bin/";
    strcat(bin, commands_list[0]);

    int pid = fork();
    if(pid == 0){
        // 子进程:仅当指定了重定向路径时才执行输出重定向
        if(INSERT_PATH[0] != NULL){
            write_file_if_exists(INSERT_PATH[0]);
        }

        // 执行目标程序,失败则报错退出
        execv(bin, commands_list);
        perror("Failed to execute command");
        exit(EXIT_FAILURE);
    }
    else if(pid > 0){
        // 父进程:等待子进程完成,然后重置重定向路径
        int status = -1;
        wait(&status);
        INSERT_PATH[0] = NULL; // 关键:父进程中重置全局状态
        return -1;
    }
    else{
        perror("Failed to fork process");
        return -1;
    }
}

关键修改说明

  • 全局状态重置:父进程在等待子进程结束后主动清空INSERT_PATH[0],确保下一次命令处理时不会继承上一次的重定向配置。
  • 重定向语义对齐:通过O_TRUNC实现文件覆盖,和Shell的>操作保持一致。
  • 错误处理增强:对系统调用的错误场景进行捕获和提示,提升程序健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 04:41:07