Когда использовать стандартный поток ошибок в приложении командной строки?

9

Есть ли рекомендация, когда использовать ошибку при написании приложения командной строки? К моему удивлению, я ничего не нашел, когда гуглял.

В частности, вопрос, который меня сейчас интересует, заключается в том, использовать ли stdoutили stderrкогда пользователь вызвал программу с недопустимыми аргументами. Тем не менее, более полный ответ очень ценится, потому что это, безусловно, не единственный случай, когда необходимо написать четкое правило для написания программы, которая ведет себя так, как этого ожидает пользователь.

UTF-8,
источник
Можно ли смешивать эти сообщения об ошибках с обычным выводом? Например, программа является фильтром данных?
thrig
Это не фильтр для данных. Это также не интерактивно. Пользователь вызывает его с аргументами (среди которых пути к файлам), программа работает, изменяет эти файлы, печатает несколько сообщений, в идеале не печатает никаких сообщений об ошибках и завершает работу.
UTF-8

Ответы:

15

Да, отображать сообщение, stderrкогда используются неправильные аргументы. И если это также приводит к закрытию приложения, выйдите с ненулевым статусом выхода.

Вы должны использовать стандартный поток ошибок для диагностических сообщений или для взаимодействия с пользователем. Диагностические сообщения включают сообщения об ошибках, предупреждения и другие сообщения, которые не являются частью вывода утилиты, когда она работает правильно («правильно», что означает, что ничего исключительного не происходит, например, файлы не найдены или что-то еще может быть).

Многие оболочки (все?) Отображают подсказки, какие пользовательские типы, меню и т. Д., stderrЧтобы перенаправление stdoutне помешало вам осмысленно взаимодействовать с оболочкой.

Следующее из сообщения в блоге на эту тему:

Это цитата Дуга Макиллроя, изобретателя труб Unix, объясняющая, как это stderrпроизошло. «v6» относится к версии конкретной версии исходной операционной системы Unix, выпущенной в 1975 году.

Все программы ставят диагностику на стандартный вывод. Это всегда вызывало проблемы, когда вывод перенаправлялся в файл, но становилось невыносимым, когда вывод отправлялся в ничего не подозревающий процесс. Тем не менее, не желая нарушать простоту модели стандартного ввода-вывода, люди терпели такое положение дел до v6. Вскоре после этого Деннис Ритчи разорвал гордиев узел, введя стандартный файл ошибок. Этого было недостаточно. С помощью конвейеров диагностика может исходить из любой из нескольких программ, работающих одновременно. Диагностика нужна для идентификации себя.
- Даг Макиллрой, «Исследовательский читатель UNIX: аннотированные выдержки из руководства программиста, 1971-1986 годы»

«Идентифицировать себя» означает просто сказать «Эй! Это я говорю! Это пошло не так: [...]»:

$ ls nothere
ls: nothere: No such file or directory

Делать это stderrпредпочтительно, так как это могло бы быть прочитано тем, кто читал stdout(но мы так lsили иначе не делаем этого , не так ли?).

Кусалананда
источник
Поэтому, когда вы спрашиваете пользователя о том, как работает приложение, вы должны напечатать вопрос на stderr? Это не звучит правильно. У вас есть источник для этого? Относится ли это только к приложениям, которые выводят не только вопросы и ответы (вывод, который пользователь может куда-то направить)?
UTF-8
@ UTF-8 Должен ли текст вопроса рассматриваться как часть результатов программы? Как насчет того, что пользователь вводит? Я не думаю, что это должно быть (так же, как снаряды не думают, что это должно быть). Но может это зависит от приложения?
Кусалананда
1
Спасибо за ваше редактирование. Тем временем я проверил поведение стандартных приложений, и они ведут себя так, как можно ожидать, что они будут вести себя после прочтения вашего ответа.
UTF-8
@ UTF-8, вы можете найти эти вопросы и ответы актуальными: unix.stackexchange.com/q/331611/22222
terdon
5

Из спецификации POSIX для стандартных потоков:

При запуске программы три потока должны быть предварительно определены и не должны открываться явно: стандартный ввод (для чтения обычного ввода), стандартный вывод (для записи обычного вывода) и стандартная ошибка (для записи диагностического вывода ).

Другими словами, ошибки, информация об отладке и все, что попадает в категорию диагностики, входит в stderr.

См. Связанный вопрос для получения дополнительной информации: отчеты о проделанной работе / информация о регистрации относятся к stderr или stdout?

Сергей Колодяжный
источник