リダイレクトとログスクリプトの出力

リダイレクトとログスクリプトの出力

次のコードスニペットを作成しようとしています。設計目標はスクリプトのすべての出力を記録することであり、ラッパーにしてはいけません。行が少ないほど良いです。

(この段階では)ユーザー入力に興味がなく、ターゲットスクリプトは非対話型で実行されます。

この作品には以下が必要です。

  • ログに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を何かに設定する必要があります

おすすめ記事