Существует ли официальное руководство по POSIX, GNU или другим правилам о том, где следует печатать отчеты о ходе работы и информацию о регистрации (например, «Doing foo; foo done»)? Лично я склонен записывать их в stderr, чтобы я мог перенаправить stdout и получать только фактический вывод программы. Мне недавно сказали, что это нехорошая практика, поскольку отчеты о ходе работы на самом деле не являются ошибками, и в stderr следует печатать только сообщения об ошибках.
Обе позиции имеют смысл, и, конечно, вы можете выбрать одну или другую в зависимости от деталей того, что вы делаете, но я хотел бы знать, есть ли общепринятый стандарт для этого. Мне не удалось найти какие-либо конкретные правила в POSIX, стандартах кодирования GNU или в любом другом широко распространенном списке лучших практик.
У нас есть несколько похожих вопросов, но они не решают эту проблему:
Когда использовать перенаправление на stderr в сценариях оболочки : принятый ответ предполагает, что я склонен делать, сохраняйте окончательный вывод программы на stdout и все остальное на stderr. Тем не менее, это просто представлено как мнение пользователя, хотя и подтверждается аргументами.
Должно ли сообщение об использовании идти в stderr или stdout? Это относится только к справочным сообщениям, но цитирует стандарт кодирования GNU. Это то, что я ищу, но не ограничивается только сообщениями о помощи.
Итак, существуют ли какие-либо официальные правила о том, где следует печатать отчеты о ходе работы и другие информационные сообщения (которые не являются частью фактического результата программы)?
stdout
вместе с результатами - это безопасный способ сделать результаты бесполезными. Если вам когда-либо понадобится передать результаты в какую-либо другую программу, указанная программа должна будет отделить результаты от счетчиков. Кроме того, если вы перенаправите вывод в файл, вы не сможете увидеть счетчики. ИМХО.stdout
То же, что сказал Сато Кацура, на самом деле является безопасным и правильным способом печати блесны и других информативных сообщений, но, как говорят многие программисты: «Молчание - это золото. Ничего не выводить, если все хорошо. так что на самом деле stderr всегда используется для этого из-за расплывчатого определения, а также stdout может нарушить последовательностьstderr
для сообщения об ошибках, кроме случаев, когда используется--verbose
флаг, и в этот момент также включаются отчеты о ходе работ.Ответы:
Posix определяет стандартные потоки таким образом :
Библиотека GNU C описывает стандартные потоки аналогично:
Таким образом, стандартные определения имеют небольшое руководство для использования потока, помимо «обычного / нормального вывода» и «вывода диагностики / ошибки». На практике часто перенаправляют один или оба этих потока в файлы и конвейеры, где проблемы прогресса будут проблемой , Некоторые системы даже отслеживают
stderr
вывод и считают это признаком проблем. Поэтому чисто вспомогательная информация о прогрессе проблематична в любом потоке.Вместо того, чтобы отправлять индикаторы хода выполнения безоговорочно в любой стандартный поток, важно понимать, что вывод хода выполнения подходит только для интерактивных потоков. Имея это в виду, я рекомендую записывать счетчики хода выполнения только после проверки, является ли поток интерактивным (например, с помощью
isatty()
) или когда он явно включен параметром командной строки. Это особенно важно для индикаторов прогресса, которые имеют смысл в поведении обновления терминала, например, в% -заполненных барах.Для некоторых очень простых сообщений о ходе выполнения («Начало X» ... «Готово с X») более разумно включить вывод даже для неинтерактивных потоков. В этом случае подумайте о том, как пользователи могут взаимодействовать с потоками, например, выполнять поиск
grep
или пейджингless
или мониторингtail -f
. Если имеет смысл видеть сообщения о прогрессе в этих контекстах, их будет намного легче использоватьstdout
.источник
N% done
и о вещах, подобныхdoing foo
иfoo done
. Последние всегда следует сохранять, поскольку они используются для отладки при перенаправлении в файл. Таким образом, ваше предложение проверить, является ли поток интерактивным, неприменимо (хотя в целом это очень хорошая идея).curl
иyum
. В этом случае я бы подумал о том, захочет ли пользователь взаимодействовать с выходными даннымиgrep
и /less
или с помощью аналогичных инструментов , и каким образом .POSIX определяет стандартную ошибку как
Это не ограничивает его использование только сообщениями об ошибках. Я бы рассматривал информацию о прогрессе как диагностический вывод, поэтому он относится к стандартной ошибке.
источник
stdout
по умолчанию буферизуется по строкам, а не буферизируетсяstderr
, поэтомуstderr
это естественный выбор для написания текста прогресса / баров / спиннеров, которые не содержат перевода строки. (Если вы пишете такой текст,stdout
вам нужно загромождать ваши выходные вызовы прогресса,stdout.flush()
чтобы сделать его видимым).stdout
, вы должны очистить даже если текст действительно содержит символ новой строки , если вы хотите , чтобы ваши отчеты о ходе работ на самом деле показать в режиме реального времени , когда перенаправлены.POSIX немного конкретнее о «диагностической информации» в Shell и Utilities , 1.4: Описание утилит по умолчанию (выделено мной):
IANASL, но я понимаю, что это означает, что stderr будет выводиться только в том случае, если утилита вернет код завершения ошибки. Поскольку это не должно быть нормальным ходом событий для успешного выполнения, утилита POSIX не должна выводить информацию о ходе выполнения, если только не происходит ошибка (если, конечно, не указано иное и т. Д.).
источник
По принципу исключения, это может идти только в stderr. Да, я знаю, что вы спрашивали об официальной спецификации, которую я не могу представить вам помимо ссылки на спецификацию POSIX, предоставленную Стивеном Киттом, в которой говорится, что stderr предназначен для диагностических целей.
Более важным моментом является то, что stdin и stdout имеют функцию, которая запрещает печатать отчеты о ходе работ на stdout - они, конечно, образуют последовательность каналов, которая в командах оболочки Unix является не просто побочным эффектом, а самой основой мощного конвейерного подхода ,
Так. Ничто, кроме реальной полезной нагрузки вашей программы, не принадлежит stdout. Если ваша программа не имеет выходных данных, то ничего не должно идти в стандартный вывод. Это оставляет stderr для всего остального , включая отчеты о проделанной работе.
Конечно, это оставляет дыру - было бы неплохо иметь «stdfluff» или что-то в этом роде, которое не предназначено ни для вывода, ни для ошибок, а для отчетов о проделанной работе, отладки и тому подобного. Фактически, ничто не мешает вам сделать это, то есть вы можете распечатать свой прогресс в файловом дескрипторе 3. Пример:
Это не дает никакого выхода. (*)
Это печатает на fd-3, который перенаправляется на стандартный вывод.
(*) Первый пример не производит вывода, но все еще немного надуман;
open
терпит неудачу и$!
будет содержатьno such file or directory
; просто возьмите это в качестве примера, конечно, не стоит так серьезно использовать. В реальной программе, если вы хотите пойти по этому пути, вы можете проверить,/dev/fd/3
пригодно ли это для использования, и принять это как подсказку, активировать ли ваши отчеты о проделанной работе; вам придется сделать это довольно рано, чтобы вас не смущали ваши собственныеopen
файлы настоящих файлов и тому подобное ...источник
fd-3
? Третья дискета?Сообщение об использовании должно идти в stdout, если пользователь вызвал его,
--help
и в stderr, если они допустили ошибку. Безусловно, печатать его на stderr неприятно, потому что это затрудняет его просмотр с помощью пейджера / grep / и т.д.Кроме того, могу я предложить третий способ: открыть / dev / tty для отчетов о проделанной работе / счетчиков / и т.д.
источник
--help
сообщениях или помощи вообще. Пожалуйста, перечитайте вопрос.