Я решил удалить свой первоначальный ответ и опубликовать новый, потому что, хотя старый был на самом деле правильным, он не очень хорошо отвечал на вопрос.Теперь, когда я понимаю, что ОП на самом деле делает , я могу ответить на этот вопрос правильно.
Вопрос на самом деле очень прост.Большинство программ, особенно программ командной строки, на большинстве платформ содержат логику, чтобы определить, был ли перенаправлен stdout
или stderr
в файл (> file
) или канал (например, | tee
).Эта логика обычно фактически скрывается в библиотеке времени выполнения, поэтому программы получают ее бесплатно, поэтому почти все они делают это, и я уверен, что это верно для mpg123
, который является относительно простым зверем.То, что я скажу ниже, будет применяться почти к любой программе.
Теперь, что эта логика делает, чтобы решить, следует ли буферизовать выводить в stdout
/ stderr
(это может сделатьдругое решение для каждого).Если вывод идет непосредственно на консоль (или, в Unix, на терминал), он вообще не буферизуется (или, возможно, только для каждой строки).Все отправляется в значительной степени, как только программа его генерирует.
Если, с другой стороны, вывод перенаправлен , тогда mpg123
обнаруживает это и записывает данные в виде кусков (часто 4k чанков) и , если общий объем вывода, сгенерированного во время работы программы, меньше размера буфера , тогда вы не увидите ничего в выходном файле или канале, пока программа не завершится,в этот момент буфер очищается, а файл закрывается (так что вы видите его тогда, как отметил OP).
Теперь, зная все это, мы можем объяснить поведение, которое OP наблюдает при запуске mpg123
,На самом деле это не связано с каким-либо запутанным жонглированием, которое mpg123
может делать с дескрипторами файлов, а изменение поведения при добавлении в -v
является лишь побочным эффектом.То, что вы видите, является прямым результатом другой стратегии буфера, используемой при перенаправлении вывода.
Итак, используя двоичный файл, связанный с OP, эта команда:
mpg123 http://148.251.184.14:8192/stream
Генерируетследующий вывод на консоль сразу (потому что ничего не буферизируется):
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
version 1.25.10; written and copyright by Michael Hipp and others
free software (LGPL) without any warranty but with best wishes
Directory: http://148.251.184.14:8192/
Playing MPEG stream 1 of 1: stream ...
ICY-NAME: Chroma Metal
ICY-URL: http://chromaradio.com
MPEG 1.0 L III cbr128 44100 j-s
ICY-META: StreamTitle='Avantasia - The Seven Angels';
Затем он продолжает воспроизводить поток через звуковую карту, что занимает довольно много времени.Приведенная выше информация записывается в stdout
(а mpg123
всегда записывает диагностическую информацию в stdout
).
Эта команда, однако, ведет себя по-разному, поскольку выходные данные буферизуются (обратите внимание на перенаправление stdout
):
mpg123 http://148.251.184.14:8192/stream 2>x.txt
Как отмечено OP, при создании потока создается файл нулевой длины, поскольку общий объем диагностического вывода помещается во внутренний буфер mpg123
s , поэтому он остается там до тех пор, пока программа не завершится, после чего выходные данные должным образом включаются в файл по указанной выше причине.
И, наконец, эта команда с добавленным в * параметром -v
:
mpg123 -v http://148.251.184.14:8192/stream 2>x.txt
создает некоторые выходные данные в x.txt
во время работы программы , поскольку буфер заполняется дополнительной диагностической информацией, которую генерирует флаг -v
и в этот момент mpg123
должен записать его на диск.Флаг -v
означает verbose
.Отсюда и дополнительный вывод.
Обратите внимание, что когда вы делаете это, данные в файле по-прежнему всегда немного отстают (потому что следующий полный буфер накапливается и не будет выводиться доон полон), поэтому добавление -v
может дать вам то, что вы хотите (или, по крайней мере, некоторые из них), но это не изменило основной проблемы.Вы можете увидеть это довольно ясно, если вы запустите указанную выше команду в одном окне консоли и tail -F x.txt
в другом.Когда вы делаете это, ничего не появляется в течение первых 5 секунд или около того.Затем появляется некоторый (частичный) вывод и так далее.
Так что я надеюсь, что все прояснится.Windows и Unix ведут себя примерно одинаково в этом отношении.Я отредактирую вопрос ОП, чтобы сделать его немного менее запутанным.Сейчас немного неопрятно.