ERRを引き起こした完全なコマンドラインを取得します。

ERRを引き起こした完全なコマンドラインを取得します。

ERR の原因となったコマンドを返すようにトラップするにはどうすればよいですか?

$function err_handler() { echo "$0 caused the error"; }

$ trap err_handler ERR

$ grep -ci "failed" test4 &>/dev/null
-bash caused the error

次のような出力が欲しかった

grep caused the error

そしておそらく(貪欲に)コマンドライン全体を置換することもできます。それは可能ですか(ハッキングなしで)?

編集: 私のシェルが KSH であることを言及しなかったことをお詫びします。

答え1

コマンド履歴が有効になっていることを確認し(非対話型シェルの場合はデフォルトでオフ)、それを使用します。

#!/bin/bash
set -o history
function trapper () {
    printf "culprit: "
    history 1
}

trap trapper ERR

# your errors go here

答え2

Bash を使用している場合は、次のパラメータを使用できます$BASH_COMMAND

BASH_COMMAND
    The command currently being executed or about to be executed, unless
    the shell is executing a command as the result of a trap, in which case
    it is the command executing at the time of the trap.

注意点がいくつかあります。1 つ目は、$BASH_COMMAND複合コマンドで失敗したコマンドのみが表示され、コマンド ライン全体は表示されないことです。

$ function err_handler { echo "error: $BASH_COMMAND" }
$ trap err_handler ERR
$ true blah blah blah && false herp derp
error: false herp derp

2 つ目は、パイプラインは最後のコマンドが失敗した場合にのみ失敗します。中間のコマンドが失敗しても最後のコマンドが成功した場合は、パイプラインは成功します。

$ echo okay | false herp derp | true lol
# err_handler not called, the last command returned true.

$BASH_COMMAND3つ目は、解析されていないコマンドラインなので、異常な状況では、コマンドラインの最初の項目は必ずしもコマンドの名前であるとは限りません。

$ false herp derp                       # This is okay.
error: false herp derp
$ {false,herp,derp}                     # An obfuscated way to write `false blah blah`
error: {false,herp,derp}
$ cmd=false
$ $cmd herp derp                        
error: $cmd herp derp

関連情報