stderrをファイルにリダイレクトし、各行の前に文字列を追加します。

stderrをファイルにリダイレクトし、各行の前に文字列を追加します。

文字列の前にstderrコマンドをファイルにリダイレクトしたいと思います。

exec >&2 "$log_file"
command

期待されるログファイル:

2021-07-13 09:34:03+07:00 [stderr] error lines ...
...

タイムスタンプは単なる例です。他のスクリプトに異なるものを使用することもできます。

私はこれを使用したいと思います:

command | xargs -n1 printf '[%s] %s\n' "`date --rfc-3339=s`" 2>> "$log_file"

ただし、これはパイプされたコマンドの終了ステータスを無視します。そして非常に遅いです。

bash(または他のシェル)からexec 2>> "$log_file"exec

ベストアンサー1

Bashではとても簡単です。

exec 2> >(perl -MDate::Format -pe 's/^/time2str("%Y-%m-%d %H:%M:%S%z [stderr] ",time)/e' > /var/log/some.log)

Perl 1行のスクリプトをスタンドアロンスクリプトに変換できます。

#!/usr/bin/perl
use Date::Format;
while(<>) {
  s/^/time2str("%Y-%m-%d %H:%M:%S%z [stderr] ",time)/e;
  print;
}

同様に、別の名前で保存/usr/local/bin/timestamp-textして実行可能にしますchmod +x /usr/local/bin/timestamp-text。その後、次のように書くことができますexec

exec 2> >(/usr/local/bin/timestamp-text > /var/log/some.log)

Bourneなどの他のシェルでは、プロセスへのリダイレクトの置き換えを使用できず、execfifoを使用する必要があります。同じ回答を書き換えたくないので、同様の質問について私が書いた他の回答をお知らせします。https://unix.stackexchange.com/a/644862/7696

ちなみに、timestamp-textスクリプト(または1行バージョン)は、日付書式設定機能が良い限り(ほとんどの言語で利用可能)、必要な言語で書くことができます。最初に実行された時刻だけでなく、変更するすべての入力行の現在時刻を照会する必要があります。それ以外の場合は、次のものを/bin/date使用できます。

気づく:日付形式libtimedate-perlモジュールはDebianパッケージにあります。パッケージにはDate::Parseモジュールも含まれています。また、他のほとんどのディストリビューションのパッケージとしても利用できる必要があります。それ以外の場合。Date::LanguageTime::Zonecpan


修正する

私はこの種のタイムスタンプを実行するように特別に設計されたプログラムがあることだけを覚えています。tsしたがって、独自のPerlやスクリプトを書く必要はありません。それにすることができますその他のユーティリティパック。

exec 2> >(ts "%Y-%m-%d %H:%M:%S%z [stderr]" > /var/log/some.log)

しかし、これはperlそれ自体スクリプトなので、次のものが必要です。Getopt::長いインストールするモジュールと必要な場合があります(使用するコマンドラインオプションに応じて)Date::Parse時間::期間、そして/または時間::高解像度。 Time::Hires は Perl に含める必要があるコア Perl ライブラリモジュールです。

おすすめ記事