こんにちは。よっしーです(^^)
今日は、bashにおけるlogging(ロギング)についてご紹介します。
背景
bashにおけるlogging(ロギング)について調査する機会があったので、そのときの内容を備忘として残しました。
この記事のソースは下記のサイトにアップしています。
実行環境について
実行環境は下記の記事を参考にお願いします。
概要
本記事のロギングは、画面への出力とファイルへの出力を同時に行います。
作成ファイル一覧
下記のファイルを作成しました。
new file: local/work/06_logging/06_logging.sh
06_logging.sh
#!/usr/bin/env bash
set -euCo pipefail
readonly LOG_OUT=./stdout.log
exec 1> >(tee -a "$LOG_OUT")
function log() {
echo "[$(date '+%Y/%m/%d %H:%M:%S.%3N')] $*"
}
log "$(which bash)"
log "$(bash --version)"
動作確認
下記のコマンドを実行します。
make build
make up
make login
cd 06_logging
chmod +x 06_logging.sh
./06_logging.sh
下記の結果が ./stdout.log に出力されていれば成功です。
root@6f6ffd746838:/work/06_logging# cat stdout.log
[2023/12/10 06:03:13.021] /usr/bin/bash
[2023/12/10 06:03:13.030] GNU bash, version 5.2.15(1)-release (aarch64-unknown-linux-gnu)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
解説
06_logging.sh
このコードは、Bashシェルスクリプトで、実行されるシェルスクリプトの動作を制御し、標準出力をファイルに記録するためのものです。以下に、コードの各部分を解説します。
#!/usr/bin/env bash
: スクリプトがBashシェルで実行されることを指定しています。この行はスクリプトがどのプログラムで実行されるべきかを指定するためのもので、ここでは/usr/bin/env
を使用してBashを呼び出します。set -euCo pipefail
: これはシェルスクリプトの設定を変更するためのものです。
-e
: エラーが発生したら即座にスクリプトを終了します。-u
: 未定義の変数を使用しようとするとエラーを発生させます。-C
: コマンドの返り値が0以外の場合、そのコマンドが非零であることを示します。-o pipefail
: パイプの途中でエラーが発生した場合、パイプ全体をエラーとして扱います。
readonly LOG_OUT=./stdout.log
: ログを記録するためのファイルパスを指定しています。readonly
は変数が読み取り専用であることを示します。exec 1> >(tee -a "$LOG_OUT")
: 標準出力(FD 1)をtee
コマンドを介して指定されたログファイルにリダイレクトします。tee -a
はファイルに追記することを示しています。function log() { ... }
:log
という関数を定義しています。この関数は、指定されたメッセージを日付とともにログとして表示します。log "$(which bash)"
: インストールされているBashの実行ファイルのパスをログに記録します。log "$(bash --version)"
: Bashのバージョン情報をログに記録します。
最終的に、スクリプトはBashの実行ファイルのパスとバージョン情報をstdout.logファイルに書き込みます。標準出力はtee
コマンドを使用して同時に表示され、ログファイルにも追記されます。また、スクリプトはエラーが発生した場合に即座に終了します。
exec 1> >(tee -a "$LOG_OUT")
exec 1> >(tee -a "$LOG_OUT")
は、Bashシェルスクリプトにおいて標準出力をリダイレクトするためのコマンドです。ここで使用されているプロセス置換(process substitution)とtee
コマンドを使って、標準出力をファイルと同時に表示する効果を得ています。以下に、このコマンドの要素を詳しく解説します。
exec
: このコマンドは、現在のシェルスクリプトプロセスに対してリダイレクトを設定します。exec
を使用することで、シェルスクリプト全体の標準出力を変更することができます。1>
:1
は標準出力(Standard Output)を表し、>
はリダイレクトを行う演算子です。つまり、この部分は「標準出力をリダイレクトする」という意味になります。>(tee -a "$LOG_OUT")
: これがプロセス置換の部分です。>(command)
の形式は、command
の出力を一時的なファイルやパイプにリダイレクトする機能を提供します。ここでは、tee -a "$LOG_OUT"
がcommand
として使われています。
tee
: 標準入力からデータを受け取り、それを同時に複数のファイルに書き込むコマンドです。-a
オプションはファイルに追記することを示します。"$LOG_OUT"
: ログファイルのパスが指定されています。このファイルに標準出力の内容が追記されます。
つまり、この行全体で言えば、「標準出力をファイルに書き込みつつ、同時にその内容を標準出力にも表示する」という効果を持っています。ログの保存と表示を同時に行い、スクリプトの実行時の標準出力をリダイレクトすることができます。
おわりに
今日は、bashにおけるlogging(ロギング)についてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント