gpt4 book ai didi

c - 如果从标准输入读取,刷新标准输出似乎没有效果

转载 作者:行者123 更新时间:2023-11-30 14:34:57 24 4
gpt4 key购买 nike

我有以下脚本:

#!/usr/bin/perl -w
use strict;
$| = 1;
foreach (1..5) {
print $_ . "\r";
sleep 1;
}
print "\n";

其行为符合预期:数字 1,2,3,4,5 在控制台上相互覆盖。

$ ./loop.pl | hexdump -C
00000000 31 0d 32 0d 33 0d 34 0d 35 0d 0a |1.2.3.4.5..|

但是,一个不同的脚本(旨在显示隐藏长时间运行的程序的大量输出,如下所示:long_running_program | tee output | ./progr)

#!/usr/bin/perl -w
use strict;
$| = 1;
while (<>) {
chomp;
print $_ . "\r";
}
print "\n";

当输入重定向时会产生不同的行为:

 perl -wle 'foreach (1..5) { print $_; sleep 1 }' | ./progr.pl

五秒钟内看不到任何输出,然后可以看到“5”。然而 hexdump 显示相同的输出(五秒后)

$ perl -wle 'foreach (1..5) { print $_; sleep 1 }' | ./progr.pl | hexdump.exe -C
00000000 31 0d 32 0d 33 0d 34 0d 35 0d 0a |1.2.3.4.5..|

这不是 Perl 特定的。以下C代码

for (int i = 0; i < 6; ++i) {
printf("%d\r", i);
fflush(stdout);
sleep(1);
}
puts("\n");

显示数字相互覆盖,但是

#define SIZE (256 * 1024)
char buffer[SIZE];
int line = 0;
while (fgets(buffer, SIZE, stdin)) {
printf("%d\r", ++line);
fflush(stdout);
}
puts("\n");

当位于管道末端时,仅在输入耗尽后显示输出。

甚至没有

setvbuf(stdout, NULL, _IONBF, 0);

似乎有帮助。

我通过 SSH 连接到远程 Linux (RHEL6) 系统以及在 Cygwin 下本地尝试了所有这些。

(经过@Fredrik 和 @usr 的修正进行编辑)

最佳答案

您正在查看错误的程序。您在管道的第二个程序中关闭了输出缓冲,但没有在第一个程序中关闭。

<小时/>

如果连接到终端,STDOUT 是行缓冲的,否则是 block 缓冲的。

行缓冲:输出换行时刷新。

block 缓冲:缓冲区填满时刷新。

由于管道(输入生成器)的第一个程序的 STDOUT 连接到管道,因此其输出是 block 缓冲的。由于缓冲区足够大,可以容纳程序的全部输出,因此您的输入生成器在退出之前实际上不会输出任何内容。

改变

perl -wle 'foreach (1..5) { print $_; sleep 1 }' | ./progr.pl

perl -wle '$| = 1; foreach (1..5) { print $_; sleep 1 }' | ./progr.pl

但是如果您无法控制该程序怎么办?有时您可以使用 unbuffer 诱使其他程序关闭缓冲。

unbuffer perl -wle 'foreach (1..5) { print $_; sleep 1 }' | ./progr.pl

关于c - 如果从标准输入读取,刷新标准输出似乎没有效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58774625/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com