私のスクリプトには、次の非常に単純な機能があります。
# Used for debug tracing.
log()
{
:
echo "log: $1"
}
一箇所でロギングをカスタマイズ/解除できるというアイデアです。とても荒いです。
これで、リリース設定でスクリプトがまったく出力を生成しないようにします。私が考えた唯一の解決策ですが、非常に乾燥していません。
TMPFILE='/tmp/tempfilewithpossiblyuniquename'
cmd 1>"$TMPFILE" 2>"$TMPFILE"
cat "$TMPFILE" | xargs log
rm "$TMPFILE"
~のためすべてのコマンド。これを改善する方法は?
編集:収集したいみんなに出力してstdout
からstderr
起動しますlog()
。その後、log()
すべてを無視したり、ファイルに書き込んだり、印刷したりするなどのジョブを選択できます。
答え1
$1
まず、この関数は送信されたすべての項目の最初の「単語」のみを記録します"$*"
。
第二に、この種のタスクを実行する方法は数え切れないほどです(POSIXの場合はしばしばそうです)。次のものを選択できます。
log() {
cat - >> "$logfile"
}
do_stuff | log
ただし、次のこともできます。
(
do_stuff
do_more_stuff
) >> "$logfile"
./thing 1> /dev/null 2> &1
すべての出力を完全に抑制する場合は、通常、以前のように「コードで」ロックするよりも、呼び出し環境(たとえば)に委ねる方が良いです。その意味は:
squashout="true" # comment this out to stop killing output
if ! [[ "true" = "${squashout-false}" ]]; then
# Redirect stdout and stderr to the null device.
exec 1> /dev/null
exec 2> /dev/null
fi
答え2
単純な出力はまったくありません。stdout
スクリプトの合計をstderr
次にリダイレクトするだけです/dev/null
。
exec >/dev/null 2>&1
これはシェル自体とそれ以降に実行されるすべてのコマンドに影響します。出力がリダイレクトされる場所を選択するには、このコマンドを条件付きで実行します。
if [ "$output_to_file" = 1 ]; then
exec > "$outputfilename" 2>&1
elif [ "$output_suppress" = 1 ]; then
exec > /dev/null 2>&1
fi
注意、自制みんな出力はおそらく良い考えではないでしょう。ユーザーはおそらく一部エラー通知。
関数を介して出力を渡してBash / ksh / Zshを実行している場合は、プロセスオーバーライドを使用できます。
#!/bin/bash
mangle_output() {
# do something smarter here
while read -r line; do
echo "output: $line";
done;
}
# redirect stdout and stderr to the function
exec > >(mangle_output) 2>&1
echo something that produces output
出力を処理するためにシェルループを使用するのは良い考えではありませんが、少なくとも速度が遅いです。望むより:シェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?。ファイルをリダイレクトまたはリダイレクトしたい場合は、SetupRedirectを/dev/null
使用してくださいexec
。