時間と状態でメッセージを記録する機能を持つBashスクリプトがあり、スクリプトの80列だけを保持したいと思います。
#!/bin/bash
log_message() {
echo "[$(date)]-[$1] : $2" >> log.txt
}
varName="John Doe"
# line break to not exceed 80 columns
log_message "WARNING" "I am "${varName}" and i want to limit this line \
to 80 columns"
ログファイルの結果が予想と異なります。
[Fri Jun 24 13:50:12 CEST 2022]-[WARNING] : I am John
Bashでこれを行う正しい方法は何ですか?
答え1
あなたの場合、問題は行の連続にあるのではなく、2番目のパラメータに二重引用符をエスケープせずに使用しているという事実にあります(@Stéphaneの答えを見ると、実際にこれを意図したかもしれません。これが良い考えではない理由については、以下を参照してください。)。試してみてください
log_message "WARNING" "I am \"${varName}\" and i want to limit this line \
to 80 columns"
以前にエスケープされていない引用符を使用した変数参照${varName}
は、実際には外部二重引用符とスプレーしたがって、log_message
呼び出しには次のパラメータが表示されます。
WARNING
I am John
(そのJohn
部分は「閉じる」二重引用符の直後にあるため、まだ2番目のタグの一部と見なされます。)Doe and i want to limit this line to 80 columns
(Doe
2番目のパラメータと同じ理由で3番目のパラメータに追加)John
ただし、関数はlog_message
最初の2つの引数のみを解釈するため、残りの文字列フラグメントは失われます。
答え2
参考までに、よりよく書くことができますlog_message
。bash
exec {logfd}>> log.txt
log_message() {
local severity="$1" message
shift
for message do
printf '[%(%FT%T%z)T]-[%s] : %s\n' -1 "$severity" "$message" >&"$logfd"
done
}
これにより、date
毎回コマンドを実行してログファイルを再度開く必要がなく、複数のメッセージを渡すことができます(各メッセージは別々の行に表示されます)。
その後、@AdminBeeはすでに述べたように行の連続に使用されます\
。 sh/bashでは、他のほとんどの言語とは異なり、引数の拡張や引用符を除いて、シェルの特殊文字を中心に回転します。結局、その部分は引用されていないまま残され"...."${var}"..."
ます${var}
。つまり、分割+グローブを経るという意味です!
log_message WARNIN\
G "I am ${varName}\
and I want to lim\
it this line to 20\
columns"
選択です。これらの行の連続(次に\
改行文字が続く)は、二重引用符の内側または外側またはhere文書で使用できますが、単一引用符内または引用符区切り文字を含むhere文書では使用できません。
これにより、log_message
以下も実行できます。
log_message WARNING \
"I am ${varName}" \
'and I want to limit' \
'the length of the lines' \
'in the log file.'
入力するlog.txt
:
[2022-06-24T13:28:46+0100]-[WARNING] : I am John Doe
[2022-06-24T13:28:46+0100]-[WARNING] : and I want to limit
[2022-06-24T13:28:46+0100]-[WARNING] : the length of the lines
[2022-06-24T13:28:46+0100]-[WARNING] : in the log file.