🐠
zshのコマンドが失敗したら履歴を残さない(precmdフックを使う)
やりたいこと
- zshで、コマンド実行が失敗したら履歴に残らないようにしたい
- とりあえず動けばよい
環境
zsh --version
zsh 5.8.1 (x86_64-ubuntu-linux-gnu)
or
zsh 5.9 (arm64-apple-darwin24.0)
他の記事でも取り上げられているが・・・
失敗したコマンドを残さない方法は紹介されているのですが、私の環境のせいなのか、書かれているzshaddhistoryフックが使えませんでした。
やりたいことは、直前のコマンドの実行結果を使って判定して、書き込みするかを決めるということです。
ワークアラウンド
git hooksの実行順は、このようになっています。
- zshaddhistory
- preexec
- precmd
自分のzsh環境でコマンド結果が出るタイミングを調べていると、precmdの段階では実行結果が反映されていました。
ということで、このprecmdフックを使うことにして.zshrcに判定処理を書きます。
.zshrc
# zsh history write on condition
function save_command() {
EXIT_STATUS=$?
if is_ignore_history "$cmd"; then
return 1
fi
if (( $EXIT_STATUS == 0 )); then
print -sr -- "$cmd"
fc -W
fi
}
# Workaround for when the exit status of the last command is available
# in precmd instead of in zshaddhistory.
autoload -Uz add-zsh-hook
# zshaddhistory() is called before precmd.
add-zsh-hook precmd save_command
テストするには
履歴ファイル~/.zsh_historyを開いて、false とかech test とか打つと記録されないことがわかります。
setoptの調整
setoptはこのようになっています。
% setopt | grep hist
extendedhistory
histexpiredupsfirst
histfindnodups
histignorealldups
histignorespace
histnostore
histreduceblanks
histverify
sharehistory
まとめ
- zshの履歴に、コマンドが失敗したら記録しない(成功したときだけ記録する)ようにしました
- 課題:コマンドが失敗したときと、コマンドがtypoしてたときと、どちらも記録されないのが困ることがある
Discussion