Обычно stdout
это строчная буферизация. Другими словами, если ваш printf
аргумент заканчивается новой строкой, вы можете ожидать, что строка будет напечатана мгновенно. Похоже, это не выполняется при использовании канала для перенаправления tee
.
У меня есть программа на C ++ a
, которая выводит строки, которые всегда \n
завершаются, в stdout
.
Когда он запускается сам по себе ( ./a
), все печатается правильно и в нужное время, как и ожидалось. Однако, если я передаю его в tee
( ./a | tee output.txt
), он ничего не печатает, пока не завершит работу, что противоречит цели использования tee
.
Я знаю, что могу исправить это, добавив fflush(stdout)
после каждой операции печати в программе на C ++. Но есть ли более чистый и простой способ? Есть ли команда, которую я могу запустить, например, для принудительной stdout
строчной буферизации даже при использовании канала?
expect
себя, посколькуunbuffer
, похоже, он не включен по умолчанию в OS X.unbuffer
это всего лишь небольшой сценарий, поэтому вам не нужно перекомпилировать весь пакет../configure && make
занимает около 10 секунд , а затем я просто переехалunbuffer
в/usr/local/bin
:)unbuffer {commands with pipes/tee}
.можешь попробовать
stdbuf
(большая) часть справочной страницы:
имейте это в виду:
вы не работаете
stdbuf
наtee
, вы работаете егоa
, так что это не должно повлиять на вас, если вы не установите буферизациюa
«потоков s вa
» s источника.Кроме того,
stdbuf
это не POSIX, а часть GNU-coreutils.источник
stdbuf
он уже доступен в используемых нами дистрибутивах Centos Linux, аunbuffer
его нет. Спасибо!-u
для отключения буферизации на стороне python:python3 -u a.py | tee output.txt
Вы также можете попытаться выполнить свою команду в псевдотерминале, используя
script
команду (которая должна обеспечить вывод в конвейер с строчной буферизацией)!Имейте в виду, что эта
script
команда не возвращает обратно статус завершения обернутой команды.источник
script -t 1 /path/to/outputfile.txt ./a
отлично работал для моего варианта использования. Он транслирует весь вывод в реальном времени,outputfile.txt
а также выводит его на стандартный вывод вашей оболочки. Не нужно было использоватьtee
Вы можете использовать setlinebuf из stdio.h.
Это должно изменить буферизацию на «буферизованную строку».
Если вам нужна большая гибкость, вы можете использовать setvbuf.
источник
setvbuf(stdout, NULL, _IOLBF, 0)
, что в точности эквивалентно.Если вместо этого вы используете классы потоков C ++, каждый
std::endl
будет неявным сбросом. Используя печать в стиле C, я думаю, что предложенный вами метод (fflush()
) - единственный способ.источник
#include <iostream> #include <unistd.h> int main(void) { std::cout << "1" << std::endl; sleep(1); std::cout << "2" << std::endl; }
. endl всегда очищает буфер, как определено здесь: en.cppreference.com/w/cpp/io/manip/endlКоманда
unbuffer
изexpect
пакета в @Paused до дальнейшего уведомления не сработала для меня в том виде, в котором она была представлена.Вместо того, чтобы использовать:
./a | unbuffer -p tee output.txt
Пришлось использовать:
unbuffer -p ./a | tee output.txt
expect
Пакет может быть установлен на:pacman -S expected
brew install expected
источник