解決済み:
数ヶ月前、私はログインシェルスクリプトに興味がありました。
最初のアイデアは、次のように関数を手動で記録することです。
add2log() {
printf "$(date)\tINFO\t%s\t%s\n" "$1" "$2" >>"$logPATH"
}
しかし、自動化したいです。たとえば、STDERRが自動的に記録されます。
久しぶりに満足のいく答えを見つけて、いよいよ共有する時間を持つようになりました。
これで、各シェルスクリプトに対して「main.sh」を使用して、ロギング機能と構成(ログと構成ファイルの設定)をアーカイブします。次のようになります。
#!/bin/bash
###################################################################
# MY HEADERS
###################################################################
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~Global vars
mainScriptNAME=$(basename "$0")
mainScriptNAME="${mainScriptNAME%.*}"
mainScriptDIR=$(dirname "$0")
version="v0.0"
scriptsDIR="$mainScriptDIR/SCRIPTS"
addonsDIR="$mainScriptDIR/ADDONS"
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~LOGGER FUNCS
manualLogger() {
# $1=PRIORITY $2=FUNCNAME $3=message
printf "$(date)\t%s\t%s()\t%s\n" "$1" "$2" "$3" >>"$logFilePATH"
}
stdoutLogger() {
# $1=message
printf "$(date)\tSTDOUT\t%s\n" "$1" >>"$logFilePATH"
}
stderrLogger() {
# $1=message
printf "$(date)\tSTDERR\t%s\n" "$1" >>"$logFilePATH"
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~LOG & CONF
createLog() {
# code to set and touch logFilePATH & confFilePATH
manualLogger "INFO" "${FUNCNAME[0]}" "Log file created."
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~MAIN
#
createLog
#run scripts
{
#
source "$scriptsDIR/file1.sh"
doSomthing1
doSomthing2
#
source "$scriptsDIR/file2.sh"
anotherFunction1
anotherFunction2
...
} 2> >(while read -r line; do stderrLogger "$line"; done) \
1> >(while read -r line; do stdoutLogger "$line"; done)
言い換えれば:
- 私が実行したいすべてのスクリプト/関数は./SCRIPTSフォルダの別のファイルにあります(私のmain.shはほぼ常に同じです)。
- STDOUTとSTDERRをキャプチャするために、これらすべてのスクリプトを{...}グループに入れます。
- 対応するSTDOUTとSTDERRは、対応するロガー機能にリダイレクトされます。
ログファイルは次のとおりです(手動ロガー、STDOUTロガー、およびSTDERRロガーの例)。
Lun 23 mai 2022 12:20:42 CEST INFO createLog() Log file created.
Lun 23 mai 2022 12:20:42 CEST STDOUT Some standard output
Lun 23 mai 2022 12:20:42 CEST STDERR ls: sadsdasd: No such file or directory
チームはすべての出力をログに収集します。代わりにリダイレクト2> >(while read ...
と。1> >(while read ...
たとえば、doSomthing1
STDOUTとSTDERRは記録されますが、doSomthing2
STDERRのみがリダイレクトされます。
答え1
表面的には、ちょうどデバッグステートメントを追加したようです。ここで「重い」とはどういう意味ですか? Bashスクリプト(またはその問題に対する他のプログラミング言語)で何かを再エコーする必要がある場合は、インタプリタに渡したことを知らせるecho
ステートメントが必要です。
スクリプト(またはコードスニペット)の特定のポイントで操作を実行したい場合は、コマンドの作成に代わる方法はありません。
IOリダイレクトを使用してさまざまなトリックを取得できますが、目的の効果を得るには、最初と最後に1つずつ2つのステートメントが必要です。
完全に文書化されたスクリプトが必要な場合はを参照してくださいset -x
。スクリプトの特定の機能のみを記録するには、set -x
suhshellでその機能を使用してください。
(set -x; func1)
答え2
専用ディレクトリにフラグファイルを使用します。
foo.bash:
#!/bin/bash
[[ -f $HOME/.local/debug/foo.debug ]] && \
source $HOME/.local/debug/foo.debug
...
foo.debug
のようなものを含め、私の好きなものをdebug_foofunction=1
すべてファイルに入れることができますfoo
。簡単に言えば、すべてのデバッグコードはオフになります。に変更すると、他のデバッグ設定(たとえば)を維持しながらデバッグをオフにできます。foofunction
debug_foofunction
rm $HOME/.local/debug/foo.debug
debug_foofunction=0
foofunction
debug_foootherfunction=1
man bash
" trap
"組み込みについて読んでください。
実際の解決策は複雑なスクリプトを書かないことです。問題セットに合ったプログラミング言語を使用してください。
必ずスクリプトをhttps://shellcheck.net
構文チェッカーに貼り付けるか、shellcheck
ローカルにインストールしてください。使用をshellcheck
開発プロセスの一部として作成します。