bashのスクリプトを書く際、下記のようにloggerコマンドでsysylogにログを出力しています。
command | logger
コマンド毎にloggerに渡すのは書くのが面倒ですし、スクリプトが見づらくなるので、以下サイトを参考に{}で囲まれた範囲をまとめてログ出力することを試みました。
シェルの入出力制御あれこれ – 複数コマンドの出力をまとめて制御する
1 2 3 4 5 6 7 8 |
logger_i="/usr/bin/logger -ip local0.info" logger_e="/usr/bin/logger -ip local0.error" { ... command1 command2 ... } 1> ${logger_i} 2> ${logger_e} |
標準出力はプライオリティinfoで、標準エラー出力はプライオリティerrorでsyslogに出力します。
ところが、書式チェックは問題ないのに、実行すると以下のメッセージが表示されます。
1 2 3 |
user@raspberrypi:~ $ sudo ./hoge.sh ./hoge.sh: 行 50: ${logger_i}: 曖昧なリダイレクトです user@raspberrypi:~ $ |
曖昧なリダイレクト(英文だと「ambiguous redirect」)とのこと。
loggerはメッセージを指定しない場合、標準入力をログに書き出すので、標準出力・標準エラー出力のリダイレクト先にしてもダメなようです。
いろいろググったところ、この記事がドンピシャっぽい。
Redirecting bash script output to syslog
参考にして以下のように書き直すと、意図通り動きました。
1 2 3 4 5 6 7 8 |
logger_i="/usr/bin/logger -ip local0.info" logger_e="/usr/bin/logger -ip local0.error" { ... command1 command2 ... } 1> >(${logger_i}) 2> >(${logger_e}) |
()で囲って「プロセス置換」することで、中間ファイル等を作らずに、loggerに標準出力と標準エラー出力を別々に渡すことができました。実は参考にさせて頂いたサイトにも記載されていたのですが、「プロセス置換」という名前からピンと来なくて、華麗にスルー(;_;)
注意点としては、プロセス置換はbashやzshの機能であるため、他のshellでは使えないとのこと。
下記サイトにて詳しく説明されていました。こんな記事を書けるようになりたいです…
bashのプロセス置換機能を活用して、シェル作業やスクリプト書きを効率化する
参考
シェルの入出力制御あれこれ – 複数コマンドの出力をまとめて制御する
Redirecting bash script output to syslog
bashのプロセス置換機能を活用して、シェル作業やスクリプト書きを効率化する