web-dev-qa-db-ja.com

STDERR.putsはRubyのputとどう違うのですか?

私はプログラミングから言語を学んでいますRuby 1.9、彼らは本の早い段階でコードのブロックにSTDERR.putsを放り込みます。

私はこの用語をグーグルで調べてウィキを作成しましたが、調査から収集できるのは診断に関係していることだけです。 Programming Ruby=によって提供されるコードのどこにも、エラー例外処理へのリンクはないようです。

コードは次のとおりです。

require_relative 'csv_reader'
reader = CsvReader.new
ARGV.each do |csv_file_name|
  STDERR.puts "Processing #{csv_file_name}"
  reader.read_in_csv_data(csv_file_name)
end

STDERR.putsが慣例外のエラー処理に使用されていることをどこかで読んだことがありますが、putsとは異なる動作をするかどうかを尋ねていると思います。

39
rubynewbie

デフォルトでは、putsはSTDOUTに書き込みます。 STDERR.putsを指定すると、出力をSTDERRハンドルに送信します。実装の動作は同じですが、STDOUTの代わりにSTDERRを使用すると、プログラムの消費者が規約によりプログラムからの出力をキャプチャしようとするため、プログラムのコンシューマに確実に影響します。ベストプラクティスは、デバッグ情報、エラー、警告、ステータスなどをSTDERRに記録し、実際のプログラム出力をSTDOUTに記録することです。

68
Palpatim

* nixベースのシステム内では、新しいプロセスが開始されると、デフォルトで次の3つのファイルハンドルが開かれます。

 0-STDIN 
 1-STDOUT 
 2-STDERR 

これらの番号は、ファイル記述子と呼ぶことができます。これは、プログラムの起動に使用しているUNIXシェルにとって重要です。 STDINは、プログラムが入力を取得することを期待する場所です(通常は、それを変更していない限りキーボード)。 STDOUTはプログラムが出力を書き込む場所(通常は変更しない限り画面)、STDERRはエラーを書き込む場所(通常は変更しない限り画面)。

上記の一般的な声明は、「あなたがそれを変更しない限り」です。このようなコマンドを実行する場合

command > file.out

次に、出力(STDOUTに書き込まれたものすべて)が画面に表示されず、file.outに表示されます。このようにコマンドを実行すると

command 2> file.err

次に、出力が画面に再び表示されますが、STDERRに書き込まれたエラーはfile.errに表示されます。実際には command > file.outは本当にcommand 1>file.out。 >記号(リダイレクト)に適用されるものはすべて、|にも適用されます。配管のシンボル。つまり、プログラムをフィルターとして実行し、STDINでデータを受信して​​STDOUTに書き込むと、他のプログラムはプログラムからデータを受信できますが、STDERRに書き込まれたデータは受信できません。 (あなたがそれを求めていない限り)

このようにこれらのコマンドの両方を一緒に使用できます。

command 1> file.out 2> file.err  # Generally you would leave out the 1

この場合、驚くべきことではありませんが、出力とエラーは2つの別々のファイルになります。 Bashには、ファイル記述子を複製するという概念もあります。これは>&演算子で行われます。次のコマンドは、STDOUTとSTDERRの両方を同じファイルに入れます。

command > file.out 2>&1

このコマンドの意味は、STDOUTをfile.outにリダイレクトするように設定するコマンドを実行してから、ファイル記述子2(STDERR)を複製(>&)して、ファイル記述子1が行く場所(file.out)

ここでは、これらの引数を使用する順序に少し注意する必要があります。上記をこのコマンドと比較してください。

command 2>&1 > file.out

これはまったく異なる結果になります。このコマンドは、コマンドを実行し、STDERR(この時点では端末)にSTDERRを複製し、STDOUTをfile.outにリダイレクトすることを示します。エラーテキストは画面に残ります。

24
Steve Weet

各プログラムは、生成されると、標準入力、出力、エラーストリームの3つの標準ファイル記述子で始まります。

標準入力ストリームは、プログラム入力を読み取る必要がある汎用ストリームです。同様に、標準出力ストリームは、プログラム出力が書き込まれる可能性のある汎用ストリームです。では、標準エラーとは何ですか?

標準出力と標準エラーの違いはわずかですが、プログラムがパイプを介して一緒に使用されるため、UNIXシステムでは非常に重要です。多くの場合、プログラムは他のプログラムの出力を入力として使用するように設計されています。これは、多くの場合パイプ演算子(|)を介して、あるプログラムの標準出力を別のプログラムの標準入力にリダイレクトすることによって行われます。これにより、標準エラーが端末に接続されたままになります。ユーザーは、端末自体でそのストリームに送信されたデータを表示するか、ログファイルにリダイレクトするか、ユーザーが希望する/dev/nullにリダイレクトするかを選択できます。 stderrに送信されるデータは必ずしもエラーメッセージである必要はないことに注意してください。プログラムの実際の出力とは別のデータです。

このパラダイムをサポートすることは、プログラムの入力、出力、およびメッセージに対する予測可能なユーザーインターフェイスを提供するため、プログラムの使いやすさにとって非常に重要です。ユーザーはこれらを適切に操作でき、多くの場合、予期しない方法で興味深いアプリケーションが発生します。

したがって、一般的に言えば、標準出力は実際の出力用であり、標準エラーはユーザーとの通信用です。

4
Matheus Moreira