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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:25:30