現在、トラップ関数内の echo ステートメントを stdout に出力する際に問題が発生しています。実行したコマンドからのすべての出力 (エラーと stdout) をログ ファイルにリダイレクトしています。ただし、エラーが発生した場合は、エラーをログ ファイルではなく stdout にリダイレクトする必要があります。
のようなことをしようと思っていましたtrap 1> on_exit EXIT
が、それについては全くわかりません。どうすればいいでしょうか?
編集:
説明のために、すべての出力 (stderr と stdout) を意図的にログ ファイルにリダイレクトしています。どの時点でもエラーが発生した場合、そのコマンドのエラー出力がログに記録されます (これが私の目的です)。また、on_exit
関数の出力をログ ファイルではなくユーザーのビュー (stdout) に出力します。現在、私のスクリプトにはログ ファイルに出力するトラップ関数があります。stdout に送信したいだけです。
#!/usr/bin/env bash
set -e
on_exit()
{
echo "An error occurred"
}
function main()
{
trap on_exit EXIT
# for looping over set of commands
$command &> "$LOGFILE"
}
main "$@"
答え1
[これは回答というよりはコメントです。何を達成しようとしているのかがよく分かりません]
スクリプトset -e
はエラーで終了するため、何かをリダイレクトするには遅すぎます。
おそらく、次のようなものをお探しでしょう:
#! /bin/bash
set -o errtrace # let functions inherit the ERR trap
exec 3>&2 # save the original stderr into fd 3
on_error() {
echo >&2 "An error occurred" # still printed to the log the 1st time
exec 2>&3 # switch back to the original stderr
trap '' ERR # disable ourselves
}
main() {
trap on_error ERR
no_such_command # this fail with an error
no_such_command # again
no_such_command # and again
}
main "$@" >/tmp/log 2>&1
実行する場合:
$ bash /tmp/err
/tmp/err: line 13: no_such_command: command not found
/tmp/err: line 14: no_such_command: command not found
$ cat /tmp/log
/tmp/err: line 12: no_such_command: command not found
An error occurred
OP のスクリプトは、元の stderr にメッセージを出力し、エラーが発生すると終了するように変更されました。
#!/usr/bin/env bash
set -o errtrace # let functions inherit the ERR trap
exec 3>&2 # save the original stderr
on_error()
{
echo >&3 "An error occurred"
exit 1
}
function main()
{
trap on_error ERR
# for looping over set of commands
$command &> "$LOGFILE"
}
main "$@"
実行する場合:
$ command=no_such_command LOGFILE=/tmp/log bash /tmp/jeg
An error occurred
$ cat /tmp/log
/tmp/jeg: line 15: no_such_command: command not found