Коли використовувати перенаправлення на 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: просто уявіть, що всі ваші сценарії будуть виведені в іншу команду через pipe. У такому випадку слід зберігати всі сповіщення в stderr, оскільки така несподівана інформація в stdout може порушити послідовність труби.

Також іноді в таких трубах:

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

вам потрібно передати щось із command2вихідних даних користувачів. Найпростіший спосіб без тимчасових файлів - stderr.


Дякую за ідею "уяві собі трубу". Іноді у мене є розгортання сценаріїв, які не виконують нічого, окрім як "сповіщають" ( echoдеякі змінні, показують, що зроблено, показують прогрес). Я вагаюся, щоб все ставити на більш жорсткі, оскільки ці повідомлення в журналі - це все, що сценарій коли-небудь виводиться. Я не впевнений, як застосувати ідею труби в цих ситуаціях.
glts

1
Програми @glts завжди змінюються та вдосконалюються. Хоча сценарії, які ви згадуєте, зараз не виводять жодних даних, вони можуть пізніше, або ви можете використовувати їх як вихідні пункти для інших сценаріїв. Якщо дотримуватися конвенції для початку, ви отримаєте набагато менше сюрпризів пізніше. ОТОХ, якщо ви просто хочете зберегти вихід у файл, тоді вам доведеться перенаправляти stderr, тож це компроміс, як і все інше.
Джо

+1 Ще парафраза: переконайтеся, що stdout завжди читається на машині чи принаймні містить корисні текстові дані у послідовному форматі.
tripleee

2

Я, як правило, пишу все, що стосується роботи програми stderr, stdoutзарезервовано для даних.

Уявіть, як програма cat. Коли ви використовуєте його для зчитування введення та передачі в іншу програму (через трубу), ви не хочете, щоб вихід був засвячений повідомленнями про стан.

Все, що може бути цікаво іншій програмі або постпроцесору моєї програми, збирається stdout, все, що стосується лише інтерна моєї заявки stderr.


0

Моя особиста перевага - надсилати повідомлення про помилки та винятки до stderrта інформаційні повідомлення stdout. IMO - stderrце будь-які винятки і, отже, моя конвенція.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.