猫什么时候完成从管道中读取数据?

猫什么时候完成从管道中读取数据?

\n给出以下代码,为什么 cat 在我输入or CTRL+后才打印管道的内容D? cat 真正打印它读到的内容的条件是什么?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void){
    int pid,p[2];
    char ch;
    pipe(p);
    if((pid=fork()) == -1){
        fprintf(stderr,"Error:can't create a child!\n");
        exit(2);
    }
    if(pid){
        close(p[0]);
        while((ch=getchar())!=EOF){
            write(p[1],&ch,1);
        }
        close(p[1]);
        wait(0);
    }else{
        close(p[1]);
        close(0);
        dup(p[0]);
        close(p[0]);
        execlp("cat","cat",NULL);
    }
    return 0;
}

答案1

cat这与、管道或缓冲无关。你的“问题”是在上游,在终端设备上。

如果您在终端键盘上输入的每个字符都可以立即被您的应用程序读取,cat那么您输入aBackspacebReturn,您的应用程序将读取athen ^?then bthen ^M,这不是您想要的,也不是您得到的。

你想要和得到的只是让它阅读a^J

你得到这个是因为在默认情况下典范模式下,终端设备驱动程序(tty线路纪律)实现了一个行编辑器允许您输入文本并对其进行编辑(功能有限),并且您输入的文本仅在您按 时才可供阅读Return

为了避免这种情况,您可以告诉终端设备保留该设置典范模式。例如,通过执行stty raw,您将看到您的应用程序并cat立即获取字符,但行为可能不是您所期望的。

您还会注意到,对于其他类型的输入(例如管道),字符一到达就会输出,如下所示:

(printf x; sleep 1; echo y) | that-command

答案2

遵循这个循环:

while((ch=getchar())!=EOF)
{
        write(p[1],&ch,1);
}

和:

char carriageReturn = 0x0D;
write( p[1], &carriageReturn, 1 );

相关内容