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

管道进程无stdout输出问题排查(cat与grep管道示例)

问题排查与修复

1. 第一个子进程参数数组未以NULL终止

execvp要求传入的参数数组必须以NULL结尾,否则会读取超出数组范围的内存,导致程序行为异常(比如cat命令无法正确执行,没有输出到管道)。

你的代码中,为第一个子进程(执行cat)构建参数数组时,仅复制了pipe_loc个元素,未添加终止的NULL:

for(int i = 0; i < pipe_loc; i++){  //args for output child
    arr_out[i] = args[i];
}
// 缺少终止NULL,导致execvp行为异常

修复:在循环结束后添加arr_out[pipe_loc] = NULL;,确保参数数组符合execvp的要求。

2. waitpid 循环条件逻辑错误

当前的等待循环条件逻辑完全错误:

while(!WIFEXITED(status_1) && WIFSIGNALED(status_1) && !WIFEXITED(status_2) && WIFSIGNALED(status_2));

该条件要求“两个子进程都未正常退出且都被信号终止”才继续等待,这几乎永远不成立,会导致父进程提前结束,可能在子进程还未完成管道数据传输时就退出,最终导致grep无输出。

修复:修改为只要任意一个子进程还未正常退出或被信号终止,就持续等待:

do {
    wpid_1 = waitpid(child_out, &status_1, WUNTRACED);
    wpid_2 = waitpid(child_in, &status_2, WUNTRACED);
} while ( (!WIFEXITED(status_1) && !WIFSIGNALED(status_1)) || (!WIFEXITED(status_2) && !WIFSIGNALED(status_2)) );

3. 冗余代码优化(非功能性问题)

第二个子进程中的break语句完全冗余,因为循环范围已经限定了i的取值,j最终会自然到达目标值,可删除该语句简化代码:

int j = 0;
for(int i = pipe_loc+1; i < argc ; i++){
    arr_in[j++] = args[i];
}
arr_in[j] = NULL;

修复后验证

修复以上问题后,cat crash.c会正确将内容写入管道,grep 'main'从管道读取输入后,其stdout并未被修改(代码仅重定向了它的stdin),匹配结果会正常打印到终端。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:25:21