bash_historyに失敗したbashコマンドを書くのを防ぐ方法

bash_historyに失敗したbashコマンドを書くのを防ぐ方法

どこでも見たことのない微妙な歴史的行動を探します。

  1. ターミナルセッション中に終了状態に関係なく、すべてのコマンドがメモリ履歴に追加されることを望みます。
  2. セッション終了後、メモリー内の記録がディスクに書き込まれている間に~/.bash_history失敗したコマンドを無視したいと思います。

推論が明確であることを願っています。セッション内の記録の最も一般的な用途の1つは、マイナーな編集または一部の環境の事実の変更後に、より良い結果を得るために最後の(失敗した)コマンドを再試行することです。

しかし同時に、私の長い歴史が悪い秩序で覆われたくありません。

私は見たこの投稿、(1) 最後のコマンドの終了状態を確認する方法、(2) インデックス別に履歴項目を削除する方法を示します。

そして私は見たこの回答trap、セッションの終わりにコマンドを実行する方法を示します。

(私も勉強しました。これは超回答です、これは歴史的な操作に関連する多くの欠点に対処するようです。それがどれほど関連性があるかはよくわかりませんが。 )

目標を達成する方法のおおよそのアイデアはありますが、bashプログラミングの経験はあまりありません。私の計画:

  • $TEMP/.bash_history_failures_IDENTIFIERIDENTIFIER複数のセッションが互いに干渉しないようにするために、各端末セッションに対して新しいファイルを作成し、いくつかのセッション固有の値(PID?)に置き換えます。
  • number=$(history 1)との組み合わせを使用して、[ $exit_status -eq 127 ]各エラーコマンドのインデックスを現在のセッションの失敗ファイルに書き込みます。
  • 終了時にコードを実行するためにフックを使用して、trapこのセッションで失敗したファイルのインデックスを繰り返す関数を呼び出して、history -d $number各項目に対して操作を実行します。
  • ~/.bash_historyHISTCONTROL最後に、私の設定に従って、残りのメモリ内書き込み(成功したコマンドのみを書き込む必要があります)を書き込むようにしました。

私の提案はうまくいくでしょうか?私は何を見落としていますか?履歴からアイテムを昇順に削除するのに問題がありますか?セッションごとに独自のファイルを生成するための優れた信頼性の高い方法は何ですか?


「失敗した」コマンドとは何ですか?

長期記録にユーザーエラーが含まれたくありません。

  • コマンドが存在しません
  • 文法エラー

他の理由でコマンドを実行できない場合(たとえば、権限不足、入力パスなし)、コマンドを正しく維持したいと思います。

心に浮かぶ2つの例は、次のようにコードの行にセミコロンを挿入することを頻繁に忘れてしまう場合です。

for pkg in $(ls ./packages); do cp ./.eslintrc.yml ./packages/$pkg/; done

私は準決勝戦を間違った場所に置いたアイテムが歴史に含まれたくありません。

一方、正しいオプションを見つけるには通常数回試みる必要があり、ほとんどcutのエラーは引数を指定したときの構文エラーです。

私の長いbashレコードが正常に動作するコマンドを取得しようとする多くの失敗した試みを見落とすことができれば幸いです。たとえば、偶然に結果のない検索を含む履歴には興味がありません。


以下を追加するように編集されました。

これハーストシェル構成ファイルにエントリを追加するなど、履歴管理のためのCLIツールは次のとおりです。

$ hstr --show-configuration

# HSTR configuration - add this to ~/.bashrc
alias hh=hstr                    # hh to be alias for hstr
export HSTR_CONFIG=hicolor       # get more colors
shopt -s histappend              # append new history items to .bash_history
export HISTCONTROL=ignorespace   # leading space hides commands from history
export HISTFILESIZE=10000        # increase history file size (default is 500)
export HISTSIZE=${HISTFILESIZE}  # increase history size (default is 500)
# ensure synchronization between bash memory and history file
export PROMPT_COMMAND="history -a; history -n; ${PROMPT_COMMAND}"
# if this is interactive shell, then bind hstr to Ctrl-r (for Vi mode check doc)
if [[ $- =~ .*i.* ]]; then bind '"\C-r": "\C-a hstr -- \C-j"'; fi
# if this is interactive shell, then bind 'kill last command' to Ctrl-x k
if [[ $- =~ .*i.* ]]; then bind '"\C-xk": "\C-a hstr -k \C-j"'; fi

hstrのコードベースでソリューションを浸食できるという予感があります。

答え1

この試み:

export PROMPT_COMMAND='LAST_COMMAND_EXIT=$? && history -a && test 127 -eq $LAST_COMMAND_EXIT && head -n -2 $HISTFILE >${HISTFILE}_temp && mv ${HISTFILE}_temp $HISTFILE'

終了ステータスが127の場合は、histfileの最後の2行(タイムスタンプとコマンド)を削除します。私にとってはうまくいきます。記録にタイムスタンプがない場合は使用してくださいhead -n -1-2

もちろん、この行を.bashrcに追加してそれを永続化する必要があります。

答え2

Bash設定ファイルに以下を追加します。

nohist() { history -d $HISTCMD; }; trap nohist ERR

編集:エラー行を簡単に検索できるので、より良いです。

ce() { eval "$BASH_COMMAND;  e='$BASH_COMMAND'"; false; }
if [[ $- == *i* ]]; then trap ce ERR; fi # capture error command
alias e='$e' # type e and then expand with ctrl-alt-e

また、再利用のためにすべての出力をキャプチャします(ただし、エコーとヒストに問題があります)。

save_output() { 
   exec 1>&3 
   { [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
   exec > >(tee /tmp/current)
}

exec 3>&1
trap save_output DEBUG

https://stackoverflow.com/a/48398357/4240654

関連情報