回答:
あなたが本当にそれを望んでいるとは思わない。私の通常のワークフローは次のようになります。
失敗したコマンドが履歴に保存されていないと、修正して再度実行するために簡単に戻すことができませんでした。
これを行うには、私は考えることができる唯一の方法は、使用することですhistory -d
の中で$PROMPT_COMMAND
。このアプローチまたはアプローチの問題は、コマンドがエラーで終了したか、ゼロ以外の終了コードで正常に完了したかを判断できないことです。
$ grep non_existent_string from_file_that_exists
$ echo $?
1
最後に間違ったコメントを付けて修正するのは良いことですが、その後すぐに混乱を招く可能性のあるゴミになります。
私のアプローチは2段階です。失敗したコマンドは保存し、後で削除します。
error_handler() {
FAILED_COMMANDS="$(history | tail -1l | cut -c -5) $FAILED_COMMANDS"
}
trap error_handler ERR
trap command signals
のcommand
いずれかsignals
が「発生」したときに実行されます。
$(command)
を実行しcommand
、その出力をキャプチャします。
コマンドが失敗すると、このコードスニペットはhistoryに保存された最後のコマンドの履歴番号をキャプチャし、将来の削除のために変数に保存します。
シンプルな、しかしで正しく動作しないHISTCONTROL
とHISTIGNORE
-コマンドが原因変数の一つに歴史に保存されていない場合、歴史の中に保存された最後のコマンドの履歴番号は、前のコマンドの一つです。そのため、誤ったコマンドが履歴に保存されない場合、以前のコマンドは削除されます。
少し複雑なバージョンで、その場合は正しく機能します。
debug_handler() {
LAST_COMMAND=$BASH_COMMAND;
}
error_handler() {
local LAST_HISTORY_ENTRY=$(history | tail -1l)
# if last command is in history (HISTCONTROL, HISTIGNORE)...
if [ "$LAST_COMMAND" == "$(cut -d ' ' -f 2- <<< $LAST_HISTORY_ENTRY)" ]
then
# ...prepend it's history number into FAILED_COMMANDS,
# marking the command for deletion.
FAILED_COMMANDS="$(cut -d ' ' -f 1 <<< $LAST_HISTORY_ENTRY) $FAILED_COMMANDS"
fi
}
trap error_handler ERR
trap debug_handler DEBUG
exit_handler() {
for i in $(echo $FAILED_COMMANDS | tr ' ' '\n' | uniq)
do
history -d $i
done
FAILED_COMMANDS=
}
trap exit_handler EXIT
説明:
Bashを終了するとき、一意の履歴番号ごとに対応する履歴エントリを削除し、削除済みのコマンドから履歴番号を継承したコマンドを削除しないように
クリアFAILED_COMMANDS
します。
FAILED_COMMANDS
重複がないことが確かな場合は、単純に反復
(つまり、書き込みfor i in $FAILED_COMMANDS
)できます。しかし、あなたはそれが(この場合には、それは常にある)最大から最小に並べ替えられないことが予想される場合は、交換してくださいuniq
とsort -rnu
。
FAILED_COMMANDS
エントリを削除すると、次のコマンドの番号がシフトされるため、履歴番号は一意で、最大から最小にソートされている必要があります。を発行するとhistory -d 2
、3番目のエントリが2番目になり、4番目が3番目になります。
そのため、このコードを使用する場合、格納されている最大数以下のhistory -d <n>
場所をn
FAILED_COMMANDS
手動で呼び出して
、コードが適切に機能することを期待することはできません。
それはおそらくフックすることをお勧めしますexit_handler
でEXIT
、あなたも、いつでも以前のそれを呼び出すことができます。