web-dev-qa-db-ja.com

stderrに書き込む

stderred を使用して、ストリーミングされたすべての出力をstderrに赤で色付けしています。正常に動作しています。しかし、自分のbashスクリプトを作成してecho 'error' 1>&2でエラーをスローすると、出力が赤で表示されません。これは、コマンドがstderrファイル記述子が指す場所に出力をリダイレクトするだけですが、メッセージをstderrに属するものとして適切にマークしないためです。そうですか? bashでstderrに適切に書き込むにはどうすればよいですか?

6
pfnuesel

プログラムがさまざまなwrite()関数を書き換えて、ファイル記述子2に出力しているかどうかを検出し、関連するエスケープコードを追加して、端末で出力を赤にしているようです。

残念ながら、シェルでは、次のようなことをすると

echo "foo" 1>&2 

関数はファイル記述子1で書き込み(または他の同様のシステムコール)を呼び出します。ファイル記述子1はシェルによってファイル記述子2にダッピングされているため、出力はfd 2に表示されます。

残念ながら、シェルでfd 2に/ direct /を書き込む方法はわかりませんが、awkを使用できます。このような関数は、引数をファイル記述子2に直接書き込みます。

error() {
  awk " BEGIN { print \"$@\" > \"/dev/fd/2\" }"
}

これはGNU awkの機能であり、POSIXの一部ではありませんが、OS Xで提供されるawkでも機能します。

6
Steven D

そのソフトウェアはwrite()システムコールをフックして、ファイル記述子2に書き込むためにstderrと呼ばれます。

これは共有ライブラリです(カーネルの再コンパイルは必要ありません)。インストールマニュアルで説明されているように、環境変数LD_PRELOAD。動的リンカーは、プログラムの実行中にその動作を変更することに影響を与える可能性があります。これらの変数は、代替の場所で共有ライブラリを検索することにより、ランタイムリンクプロセスを調整します。

実行可能ファイル/bin/bash自体はそのような変数を尊重しないため、bash自体は、変更されたものではなく、システムコールの元のパレットを使用します。質問で述べたリダイレクトはbashで発生しました。 echoの実行可能ファイルにはありません。 echoが(bashを介さずに)エラー記述子を単独で参照できる場合、出力は赤になります。

Pythonはstderrに書き込むことができます。証明を見てください(赤で表示されます):

python -c 'import os; os.write(2, "error")'
4
chaos

ヘルパー関数を作成します。

echoerr() { printf "\033[0;31m%s\n\033[0m" "$*" >&2; }

そしてどこでもそれを使用してください:

echoerr "something went wrong here"

これはstderr(>&2)と色の変更(ここからの解決策 https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux ) 。

0
VasyaNovikov