web-dev-qa-db-ja.com

標準出力を中断せずにbash -x出力をログファイルに送信します

スクリプトを実行しているユーザーに表示される標準出力を変更せずに、-xオプションを指定してbashスクリプトを実行して表示される情報をファイルに送信する方法はありますか?

これは、頻繁に変更するbashスクリプトに実装したいデバッグ機能です。

とても有難い。

12

-xからの出力は、stdoutではなくstderrに送られます。しかし、それでも問題になる可能性があります。多くのスクリプトがstderrの内容に機能的に依存しており、場合によってはデバッグストリームとstderrストリームを混在させるのは面倒です。

Bashバージョン> 4.1では別のソリューションが提供されています。BASH_XTRACEFD環境変数を使用すると、デバッグストリームの送信先となるファイル記述子を指定できます。これは、ファイル、パイプ、またはその他のUNIXの優れた点です。

# Use FD 19 to capture the debug stream caused by "set -x":
exec 19>/tmp/my-script.log
# Tell bash about it  (there's nothing special about 19, its arbitrary)
export BASH_XTRACEFD=19

# turn on the debug stream:
set -x

# run some commands:
cd /etc
find 
echo "Well, that was fun."

# Close the output:
set +x
exec 19>&-

# See what we got:
cat /tmp/my-script.log

もう少しいじって、stdoutやstdinストリームで「ティー」を行うなど、他のことを実行し、それらをデバッグ出力とインターリーブして、ログをより完全にすることができます。これの詳細については、 https://stackoverflow.com/questions/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself を参照してください。

代替案に対するこのアプローチの大きな利点は、デバッグ出力をstdoutまたはstderrに注入することにより、スクリプトの動作が変更される危険性がないことです。

21
Stabledog

set -xは標準出力に何も送信しないので、問題はありません。 doesが行うことは、デフォルトでコンソールに送られる標準エラーに書き込むことです。

あなたがしたいことは、次のようにstdoutを別のファイルにリダイレクトすることです:

/bin/sh -x /my/script/file 2>/my/log/file
4
womble

man teeをご覧ください。

tee commandname filenameのように実行すると、stdoutへのコマンド出力が表示され、filenameにも書き込まれます。

1
Sven