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

C语言调用execv时管道失效 execlp等exec族函数正常问题咨询

问题根本原因

你代码的问题出在execv函数的使用不符合规范,具体有两处错误:

  • 第一,execv的第二个参数要求是以NULL结尾的字符串数组,用来标记参数列表结束,你当前传入的字符串数组没有末尾的NULL哨兵,会导致execv读取参数时越界,参数解析错误。
  • 第二,execv不会自动搜索PATH环境变量查找可执行文件,第一个参数必须传入可执行文件的完整路径,你直接传"cat"、"grep"如果当前目录没有对应程序会直接执行失败。

修复方案

可以选择两种修改方式,任选其一即可:

方式1:保留execv,补全路径和末尾NULL

先确认系统中cat、grep的完整路径(通常为/bin/cat、/bin/grep,可以用which cat、which grep命令确认),然后补全参数数组的NULL:

int p_fds[2];
pipe(p_fds);

int pid_left = fork();
if (pid_left == 0){
    dup2(p_fds[1],STDOUT_FILENO);
    close(p_fds[0]);
    close(p_fds[1]);
    // 补全cat的全路径,参数数组末尾加NULL
    execv("/bin/cat", (char*[]){ "cat", "afile", NULL });
    exit(1);
}

int pid_right = fork();
if (pid_right == 0){
    dup2(p_fds[0], STDIN_FILENO);
    close(p_fds[1]);
    close(p_fds[0]);
    // 补全grep的全路径,参数数组末尾加NULL
    execv("/bin/grep", (char*[]){ "grep", "something", NULL });
    exit(1);
}

close(p_fds[0]);
close(p_fds[1]);
waitpid(pid_left, NULL, 0);
waitpid(pid_right, NULL, 0);

方式2:替换为execvp,无需写全路径

execvp和execlp逻辑一致,会自动搜索PATH找可执行文件,只需要补全参数数组末尾的NULL即可:

int p_fds[2];
pipe(p_fds);

int pid_left = fork();
if (pid_left == 0){
    dup2(p_fds[1],STDOUT_FILENO);
    close(p_fds[0]);
    close(p_fds[1]);
    // 用execvp,参数数组末尾加NULL
    execvp("cat", (char*[]){ "cat", "afile", NULL });
    exit(1);
}

int pid_right = fork();
if (pid_right == 0){
    dup2(p_fds[0], STDIN_FILENO);
    close(p_fds[1]);
    close(p_fds[0]);
    // 用execvp,参数数组末尾加NULL
    execvp("grep", (char*[]){ "grep", "something", NULL });
    exit(1);
}

close(p_fds[0]);
close(p_fds[1]);
waitpid(pid_left, NULL, 0);
waitpid(pid_right, NULL, 0);

两种修改后都可以正常实现cat afile | grep something的管道效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 14:54:03