У меня есть следующий сценарий:
#!/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)