Когда использовать перенаправление на stderr в сценариях оболочки


15

Я знаю, что хорошо работающие утилиты, такие как grep, выводят «нормальные» сообщения в stdout и сообщения об ошибках в stderr.

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

Когда я пишу сценарии оболочки самостоятельно, мне часто бывает трудно решить, какой вывод и какие сообщения я должен представлять на stderr, или мне вообще стоит беспокоиться.

Я хотел бы знать о передовой практике: когда перенаправление некоторого сообщения в stderr требуется и разумно, а когда нет?

«Это зависит», конечно, но есть ли у вас какие-то идеи, которые помогут мне принять эти решения?

Чтобы этот субъективный вопрос соответствовал формату, я хотел бы предложить ответы, которые касаются «почему» и основаны на опыте и, если возможно, подкреплены фактами.


@rush это прекрасно объясняет. Я обычно печатаю отчеты о проделанной работе в stderr для длинных скриптов.
Terdon

Ответы:


12

Когда я пишу сценарии оболочки самостоятельно, мне часто бывает трудно решить, какой вывод и какие сообщения я должен представлять на stderr, или мне вообще стоит беспокоиться.

Молчание - золото. Ничего не выводить, если все хорошо.

Я хотел бы знать о передовой практике: когда перенаправление некоторого сообщения в stderr требуется и разумно, а когда нет?

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

Также иногда в трубах, как этот:

command1 | while read line ; do command2 ; done | command3

вам нужно передать что-то из command2вывода пользователей. Самый простой способ без временных файлов - это stderr.


Спасибо за идею "представь себе трубу". Иногда у меня есть сценарии развертывания, которые ничего не делают, кроме «уведомляют» ( echoнекоторые переменные показывают, что было сделано, показывают прогресс). Я не решаюсь поставить все на stderr, так как эти сообщения журнала - это все, что скрипт когда-либо выведет. Я не уверен, как применить идею трубы в этих ситуациях.
glts

1
Программы @glts всегда модифицируются и улучшаются. Хотя упомянутые вами сценарии не выводят никаких данных сейчас, они могут появиться позже, или вы можете использовать их в качестве отправной точки для других сценариев, которые это делают. Если вы начнете следовать соглашению, вы получите гораздо меньше сюрпризов позже. OTOH, если вы просто хотите сохранить вывод в файл, то вам нужно перенаправить stderr, так что это компромисс, как и все остальное.
Джо

+1 Еще один парафраз: убедитесь, что стандартный вывод всегда машиночитаемый или хотя бы содержит полезные текстовые данные в согласованном формате.
tripleee

2

Я вообще пишу все, что относится к работе приложения stderr, stdoutзарезервировано для данных.

Представьте себе приложение, как cat. Когда вы используете его для чтения ввода и передачи его другому приложению (через канал), вы не хотите, чтобы вывод был завален сообщениями о состоянии.

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


0

Мое личное предпочтение - отправлять сообщения об ошибках, исключения stderrи информационные сообщения stdout. ИМО, stderrдля любых исключений и, следовательно, мое соглашение.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.