C语言管道传递输出前如何统计字节数并存入文本文件
问题排查与修复方案
现有代码的核心问题
- 读取逻辑错误:
getc(stdout)本身是无效操作,stdout是输出流,无法从中读取数据,这是字节数始终统计为0的直接原因。且统计逻辑放在命令执行之前,完全拿不到目标命令的输出内容。 - 文件写入模式错误:使用
"w"模式打开统计文件,每次打开都会清空文件原有内容,自然只会保留最后一次写入的记录。 - 逻辑时序错误:现有逻辑是先统计、再执行命令,完全没有把命令输出和统计、管道传递关联起来,无法实现“统计后再把输出传给下一级管道”的需求。
修复思路
每个管道阶段的子进程需要按如下逻辑调整:
- 新建管道捕获当前命令的执行输出
- 读取管道中的内容,同步统计字节数并把内容原封不动转发到标准输出,传给下一级管道
- 统计完成后用追加模式写入统计文件,避免覆盖之前的记录
参考实现代码
#include <unistd.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> // 每个管道阶段的子进程执行逻辑 void run_command(int i, char* tabCommande[]) { int pipe_fd[2]; if (pipe(pipe_fd) == -1) error_and_exit(); pid_t cmd_pid = fork(); if (cmd_pid == -1) error_and_exit(); if (cmd_pid == 0) { // 子进程执行目标命令,输出重定向到管道写端 close(pipe_fd[0]); dup2(pipe_fd[1], STDOUT_FILENO); close(pipe_fd[1]); execlp("/bin/sh", "sh", "-c", tabCommande[i], (char *)NULL); error_and_exit(); } else { // 父进程读管道内容,统计+转发 close(pipe_fd[1]); int bytes = 0; char buf[4096]; ssize_t n; // 用a模式打开文件追加写入,不会覆盖历史记录 FILE *f = fopen("count.txt", "a"); if (!f) error_and_exit(); while ((n = read(pipe_fd[0], buf, sizeof(buf))) > 0) { bytes += n; // 原内容转发到标准输出,传递给下一级管道 write(STDOUT_FILENO, buf, n); } close(pipe_fd[0]); waitpid(cmd_pid, NULL, 0); fprintf(f, "%d : %d\n", i, bytes); fclose(f); exit(0); } }
补充说明
如果要求统计记录严格按照管道阶段的顺序写入,需要额外增加同步逻辑:比如所有子进程将统计结果通过IPC发给主进程,主进程统一按顺序写入文件,避免多进程并行执行导致的写入顺序乱序问题。
内容的提问来源于stack exchange,提问作者BrokenStarz111
相关产品推荐
相关产品推荐

