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

使用execvp运行grep命令保存输出到文件时出现报错如何解决?

报错原因
  • 通配符*、重定向符号>都是shell提供的预处理功能,不属于grep本身的参数逻辑。execvp函数会直接加载执行grep程序,不会启动shell做参数解析,因此grep会把*、>都当做普通文件名去读取,自然找不到对应文件,抛出你遇到的报错。
  • 输出重定向的本质是修改进程的标准输出文件描述符映射,不是靠给目标程序传参数实现,因此直接把>和输出文件名放到参数列表里也不会触发重定向逻辑。
修复方案

这里提供两种可行的实现方式:

方案1:通过shell执行命令(最简单)

直接让sh解释执行整行命令,shell会自动完成通配符展开、重定向处理,修改后的代码如下:

#include<iostream>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
using namespace std;
int main(){
    pid_t pid = fork();
    int status = 0;
    // 交给sh处理命令解析、通配符、重定向
    char* args[] = {"sh", "-c", "grep -n out * > output.txt", NULL};
    if(pid == 0){
        cout<<"I am Child Process\n";
        execvp("sh", args);
        // execvp执行失败才会走到下面
        perror("execvp failed");
        exit(EXIT_FAILURE);
    }
    else if(pid > 0){
        cout<<"I am Parent Process\n";
        wait(&status);
    }   
    else{
        perror("fork failed");
    }

    return 0;
}

方案2:手动实现重定向(不依赖shell)

如果不想额外启动shell进程,可以在子进程中手动修改文件描述符实现重定向,通配符可以用glob函数解析,示例代码如下:

#include<iostream>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<glob.h>
using namespace std;
int main(){
    pid_t pid = fork();
    int status = 0;
    if(pid == 0){
        cout<<"I am Child Process\n";
        // 1. 打开输出文件,实现重定向
        int fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
        if(fd < 0){
            perror("open output file failed");
            exit(EXIT_FAILURE);
        }
        // 将标准输出重定向到输出文件
        dup2(fd, STDOUT_FILENO);
        close(fd);

        // 2. 解析通配符*匹配的文件
        glob_t glob_res;
        if(glob("*", 0, NULL, &glob_res) != 0){
            perror("glob failed");
            exit(EXIT_FAILURE);
        }

        // 3. 构造grep参数
        char** args = new char*[glob_res.gl_pathc + 4];
        args[0] = (char*)"grep";
        args[1] = (char*)"-n";
        args[2] = (char*)"out";
        for(int i=0; i<glob_res.gl_pathc; i++){
            args[3 + i] = glob_res.gl_pathv[i];
        }
        args[3 + glob_res.gl_pathc] = NULL;

        execvp("grep", args);
        perror("execvp failed");
        globfree(&glob_res);
        delete[] args;
        exit(EXIT_FAILURE);
    }
    else if(pid > 0){
        cout<<"I am Parent Process\n";
        wait(&status);
    }   
    else{
        perror("fork failed");
    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:57:02