fork()创建子进程管道传多行数据,more仅显首行问题咨询
问题解答:父进程分批次发送数据,子进程用
more仅显示首行 先直接给结论:完全不需要一次write发送全部字符串,你可以分多次调用write逐行发送,子进程的more命令依然能只显示首行"Line 1"——关键在于more的行为逻辑和管道的特性。
为什么不需要一次性发送?
more命令默认会读取输入直到显示满一屏(终端默认高度下首行就是第一屏的内容),然后暂停等待用户输入。但管道是流式传输的:父进程每次write的数据会被追加到管道缓冲区,子进程的more会从管道读取数据,一旦读到足够显示首行的内容,就会停止读取并暂停(即使管道里还有后续数据)。
不过要注意一个细节:如果父进程在发送完首行后立刻暂停,子进程的more会因为管道未关闭且没有更多数据,进入等待状态;但如果父进程持续发送后续行,more依然只会停在首行,直到用户按空格才会继续——这正好符合你的需求。
实现要点
- 管道的创建与文件描述符管理:父进程要关闭读端
fd[0],子进程关闭写端fd[1],并将读端重定向到标准输入(这样more就能从管道读取数据)。 - 子进程的执行逻辑:用
execlp调用more,不需要额外参数,因为more默认从标准输入读取。 - 父进程的发送逻辑:可以循环调用
write逐行发送"Line i",不需要一次性拼接所有内容。
完整代码示例
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main() { pid_t pid; char buf[30]; int fd[2], i, max; printf("请输入要发送的行数:"); scanf("%d", &max); if (pipe(fd) < 0) { perror("pipe 创建失败"); exit(EXIT_FAILURE); } pid = fork(); if (pid < 0) { perror("fork 失败"); exit(EXIT_FAILURE); } if (pid == 0) { // 子进程:关闭写端,将读端重定向到stdin,执行more close(fd[1]); dup2(fd[0], STDIN_FILENO); close(fd[0]); // 调用more,默认从stdin读取 execlp("more", "more", NULL); perror("execlp 失败"); exit(EXIT_FAILURE); } else { // 父进程:关闭读端,逐行发送数据 close(fd[0]); for (i = 1; i <= max; i++) { snprintf(buf, sizeof(buf), "Line %d\n", i); write(fd[1], buf, strlen(buf)); // 加个小延迟,更明显看到more停在首行的效果 sleep(1); } close(fd[1]); // 关闭写端,子进程的more会收到EOF(但此时more已经停在首行) wait(NULL); // 等待子进程结束 } return 0; }
测试效果
运行程序后输入任意大于1的数字(比如5),你会看到终端显示:
Line 1 --More--(1%)
即使父进程还在持续发送后续的"Line 2"到"Line 5",more依然停在首行,直到你按空格键才会继续显示后续内容——完全符合你的需求。
内容的提问来源于stack exchange,提问作者DeyL Xazo
相关产品推荐
相关产品推荐

