トラップ関数のエコーを標準出力にリダイレクトする

トラップ関数のエコーを標準出力にリダイレクトする

現在、トラップ関数内の 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

関連情報