私はシェルスクリプトがスクリプトの呼び出し方法を変更せずにすべての出力を外部ファイルに書き込んで、各行stdout
(stderr
およびいくつかの追加項目)にタイムスタンプを追加したいと思います。出力リダイレクトはスクリプト自体内で発生する必要があります。また、スクリプトやパイプラインコマンドの既存のコードを個別に変更しないでください。理想的には、スクリプトに数行を追加するだけです。
次の2つの答えを使用してください。
Bashで実行できるポイントに達しました。
#! /usr/bin/env bash
CUSTOM_PREFIX1="FancyScript"
CUSTOM_PREFIX2="SomeRunID_12-3-4.5"
LOG_FILE="/var/log/script.log"
touch $LOG_FILE
exec 1>> >(while IFS= read -r line; do printf '[%s] %s %s: %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "${CUSTOM_PREFIX1}" "${CUSTOM_PREFIX2}" "${line}"; done >> "${LOG_FILE}")
exec 2>&1
# Script continues...
d
echo "Hello"
上記のスクリプトを実行すると、出力は生成されず、次のログファイルが生成されます。
# cat /var/log/script.log
[2022-02-23 03:11:45] FancyScript SomeRunID_12-3-4.5: Development/shell_log.sh: line 12: d: command not found
[2022-02-23 03:11:45] FancyScript SomeRunID_12-3-4.5: Hello
これまでは大丈夫でしたが、2つを変えたいです。
sh
Bashに依存せずにPOSIXシェル()で動作するようにしてください。普通sh
嫌いexec 1>> >(...)
(while IFS= read ....)
私はこれを最も古い子プロセスではなく、スクリプト自体内の関数にパイプしたいと思います。それはまるでpipe_log() {...}
答え1
私の考えではlogger
この目的のために特別に書かれています:システムログファイルに書き込みます。
詳細については、ユーティリティlogger(1)
マニュアル(man logger
)と上記のPOSIX仕様リンクを参照してください。
答え2
最大高級Unixツールボックスのテキスト処理ユーティリティはex
/vi
およびでawk
、m4
どちらも1970年代から使用されました。それらのどれも時間フォーマット機能を持っていません(POSIXを使用するとawk
epoch時間を取得でき、srand()
awkまたはviのいくつかの実装には拡張として時間フォーマット機能がありますが)。
perl
しかし、POSIXは1980年代半ばから非常に一般化されており、実装が1つしかないため、POSIXは標準化に参加する必要はありません。
したがって、いつでもsh
スクリプトを次のようにラップできます。
{
your-script here
} 2>&1 | perl -MPOSIX -pse '
$_ = strftime("[%Y-%m-%dT%T%z]", localtime) . " $prefix$_"
' -- '-|=1' "-prefix=$CUSTOM_PREFIX" >> /path/to/file.log
各行にタイムスタンプを追加します。
これらのタイムスタンプは%z
明確で後処理が可能です。
答え3
上記は、logger
以前のシステムロギング環境に関するものです。最新のシステムベースのシステムでは、このsystemd-cat
ユーティリティがより適しています。
echo 'my message' | systemd-cat -p info -t /path/to/script/executing/this