Используя тройник с непрерывным выводом C-программы
Это должно быть действительно просто, но я не могу поймать это.
Это тривиальная программа на C, пишущая на стандартный вывод:
root@oceanLondon:~/tst# cat tst.c
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
for (; ;) {
printf("Hello world!\n");
sleep(1);
}
return 0;
}
Теперь, если я хочу записать вывод на мой экран и файл:
root@oceanLondon:~/tst# ./tst |tee file
это просто не работает, у меня пустой экран и пустой файл.
если я делаю программу, которая выходит, то она отлично работает, например,
root@oceanLondon:~/tst# ls |tee file
Makefile
file
qq
tst
tst.c
tst.o
root@oceanLondon:~/tst# cat file
Makefile
file
qq
tst
tst.c
tst.o
root@oceanLondon:~/tst#
Это какая-то проблема с буферизацией? И может кто-нибудь помочь мне сделать это в программе продолжения, пожалуйста?
2 ответа
Стандартный поток вывода является буферизованной строкой, если можно определить, что поток относится к интерактивному устройству (например, терминалу), в противном случае он полностью буферизован, поэтому существуют случаи, когда printf
не сбрасывается, даже если для печати выводится новая строка, например, по конвейеру или с перенаправленным выводом;
> tst | tee file
> tst > file
призвание fflush(stdout)
после printf()
решит проблему.
Связанный текст от C99
раздел 7.19.3
говорится, что;
Когда поток не буферизован, символы должны появляться из источника или в месте назначения как можно скорее. В противном случае символы могут накапливаться и передаваться в среду хоста или из нее в виде блока.
Когда поток полностью буферизован, символы предназначены для передачи в или из среды хоста как блок, когда буфер заполнен.
Когда поток буферизуется строкой, символы предназначены для передачи в или из хост-среды в виде блока, когда встречается символ новой строки.
При первоначальном открытии стандартный поток ошибок не полностью буферизован; стандартные входные и стандартные выходные потоки полностью буферизуются тогда и только тогда, когда можно определить, что поток не ссылается на интерактивное устройство.
Кажется, что ваша проблема в том, что stdout
буферизируется и не отображается после новой строки. Вы можете принудительно отобразить его, сбросив его после выражения printf:
fflush(stdout);
Кроме того, вы можете отключить буферизацию с помощью:
setbuf(stdout, NULL);
Также обратите внимание, что stderr
не буферизируется, и вы можете проверить, является ли проблема буферизованной, распечатав stderr
вместо stdout
,
Как вы заметили, вы также можете использовать stdbuf
(больше информации с этим ответом).