シェルスクリプトでstderrへのリダイレクトを使用する場合


15

grepのような行儀の良いユーティリティは、stdoutに「通常の」メッセージを、stderrにエラーメッセージを出力することを知っています。

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

シェルスクリプトを自分で書いているとき、stderrにどの出力とメッセージを表示するか、または気にする必要があるかどうかを判断するのが難しいことがよくあります。

私は良い習慣について知りたいです:いつメッセージをstderrにリダイレクトするのが適切であり、そうでないのか?

「依存します」は確かですが、これらの決定を下すのに役立つ洞察はありますか?

この主観的な質問を形式に合うようにするために、「なぜ」に対処し、経験と可能であれば事実に裏打ちされた情報が得られる答えを奨励したいと思います。


@rushはそれを完璧に説明しています。私は通常、長いスクリプトの進捗レポートを標準エラー出力に出力します。
テルドン

回答:


12

シェルスクリプトを自分で書いているとき、stderrにどの出力とメッセージを表示するか、または気にする必要があるかどうかを判断するのが難しいことがよくあります。

沈黙は金なり。すべてが正常であれば、何も出力しません。

私は良い習慣について知りたいです:いつメッセージをstderrにリダイレクトするのが適切であり、そうでないのか?

stderrをstdoutから分離する最も簡単な方法:すべてのスクリプト出力がパイプ経由で別のコマンドにリダイレクトされることを想像してください。その場合、すべての通知をstderrに保持する必要があります。stdoutのこのような予期しない情報により、パイプシーケンスが中断される可能性があるためです。

また、このようなパイプでは時々:

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

command2ユーザー出力に何かを渡す必要があります。一時ファイルを使用しない最も簡単な方法は、stderrです。


「パイプを想像する」アイデアをありがとう。時々、「通知」以外の何もしないスクリプトをデプロイします(echoいくつかの変数、実行内容の表示、進行状況の表示)。これらのログメッセージはすべてスクリプトが出力するものなので、すべてをstderrに置くことをtoします。これらの状況でパイプのアイデアを適用する方法がわかりません。
glts

1
@gltsプログラムは常に修正および改善されています。言及したスクリプトは現在データを出力していませんが、後で出力したり、実行する他のスクリプトの開始点として使用したりする場合があります。慣例に従えば、後で驚くことはほとんどないでしょう。OTOH、出力をファイルに保存するだけの場合は、stderrをリダイレクトする必要があるため、他のすべてと同様にトレードオフになります。
ジョー

+1別の言い換え:stdoutが常に機械可読であること、または少なくとも一貫した形式の有用なテキストデータが含まれていることを確認してください。
トリプリー

2

Iするアプリケーションの操作に関連する一般的書き込みはすべてstderrstdoutデータ用に予約されています。

のようなアプリケーションを想像してくださいcat。これを使用して入力を読み取り、(パイプを介して)別のアプリケーションに渡す場合、出力にステータスメッセージが散らばらないようにする必要があります。

別のアプリケーションや私のアプリケーションのポストプロセッサーにとって興味深いかもしれないものはstdoutすべて、私のアプリケーションの内部にのみ関連するものはすべてしようとしているstderr


0

私の個人的な好みは、エラーメッセージと例外を通知メッセージに送信stderrすることstdoutです。IMO stderrは例外のためであり、したがって、私の慣例です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.