使用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
相关产品推荐
相关产品推荐

