
次のコードスニペットを作成しようとしています。設計目標はスクリプトのすべての出力を記録することであり、ラッパーにしてはいけません。行が少ないほど良いです。
(この段階では)ユーザー入力に興味がなく、ターゲットスクリプトは非対話型で実行されます。
この作品には以下が必要です。
- ログにstdoutを出力し、常にコンソールにエコーされます。
- デバッグが有効になっている場合は、stderrをログに出力してコンソールにエコーします。
- stderrメッセージにはタイムスタンプと他の便利なプレフィックスが必要です。
現在、最新バージョンのbash(4.2+?)でのみテストされています。たとえば、Ubuntuではうまく動作しますが、CentOS6では正しく動作しません。
DEBUG_LOG="${0##*/}.log"
# copy stdout to log always and echo to console
exec > >(tee -a ${DEBUG_LOG})
# copy stderr to log only, unless debugging is enabled
[ $DEBUG_TEST = "true" ] \
&& exec 2> >(tee -a ${DEBUG_LOG} >&2) \
|| exec 2>> ${DEBUG_LOG}
だからこれ...
# Expand escaped characters, wrap at 70 chars on spaces,
# and indent wrapped lines
msg_log() {
echo -e "$(date +%T) ${0##*/}: $1" \
| fold -w70 -s | sed '2~1s/^/ /' >&2;
}
msg_con() {
if [ "${DEBUG_TEST}" = "true" ]; then
msg_log "$1"
else
echo -e "$1" | fold -w70 -s | sed '2~1s/^/ /';
fi
}
echo
たとえば、これらのmsgプロシージャの1つを呼び出すことができますmsg_con "hello world"
。
また、スクリプト出力は、呼び出し時に設定された環境変数(例えば DEBUG_TEST=true myscript
。
一部のシェル(ビジボックスなど)では、execが機能しない可能性があることを読みました。 mkfifoとフォークの組み合わせがありますhttps://stackoverflow.com/a/5200754同様のことをしましたが、必ずしも必要でない限り、フォークを使用しないことをお勧めします。
bashの例を好みます。しかし、shで動作するものや移植性が良い方が良いでしょう。どんなアイデアがありますか?
答え1
function startLogging {
exec > >(gawk -v pid=$$ '{ print strftime("%F-%T"),pid,$0; fflush(); }' | tee -a $logfile)
[ ! -z "$DEBUG" ] && exec 2>&1 || exec 2> >(gawk -v pid=$$ '{ print strftime("%F-%T"),pid,$0; fflush(); }' >>$logfile)
echo "=== Log started for $$ at $(date +%F-%T) ==="
}
$ logfileを何かに設定する必要があります
答え2
exec > filename
shで動作する必要があり、実際にはbusybox v1.15.3(2011年11月)で動作します。しかし、プロセスの交換は>(command)
bash拡張なので移植性はありません。スクリプトでは使用しないでください。なぜ>>
十分ではないのですか?
exec 1>>${DEBUG_LOG}
exec 2>>${DEBUG_LOG}
別の解決策は、スクリプトの外部でリダイレクトを指定することです。スクリプトがバックグラウンドで呼び出されると(cronやシステムスクリプトなどで)、次のように呼び出す必要があります。
./my_script 1>>${DEBUG_LOG} 2>>${DEBUG_LOG}
スクリプトを手動で呼び出して出力を表示するには、リダイレクトせずに呼び出すだけです。
答え3
これら2つの例は、あなたが言及した内容を達成します
echo -n $(date) >> $DEBUG_LOG
command 2>&1 | tee -a $DEBUG_LOG
または
echo -n $(date) >> $DEBUG_LOG
command >> $DEBUG_LOG 2>&1
答え4
tee
コマンドやコマンドを使用でき、script
どちらも非常に便利です。