私の知る限り、あなたが望むことをすることは不可能です。これは、改善できる bash の履歴処理のバグだと思います。
export HISTCONTROL=ignoreboth:erasedups # no duplicate entries
shopt -s histappend # append history file
export PROMPT_COMMAND="history -a" # update histfile after every command
これにより、メモリ内の履歴が一意に保たれますが、複数のセッションからの履歴が同じファイルに保存されますが、ファイル自体の履歴は一意に保たれません。history -a
直前のコマンドと同じでない限り、新しいコマンドをファイルに書き込みます。erasedups
設定がメモリ内で行うように、完全な重複除外は行いません。
このばかげた動作を確認するには、新しい端末セッションを開始し、履歴を調べます。たとえば、繰り返しエントリが表示されますls
。コマンドを実行するls
と、複製ls
されたものはすべてメモリ内の履歴から削除され、最後のものだけが残ります。履歴ファイルで複製されたコマンドを実行すると、メモリ内の履歴は短くなりますが、履歴ファイル自体は大きくなり続けます。
独自のスクリプトを使用して、必要に応じて履歴ファイルをクリーンアップします。
# remove duplicates while preserving input order
function dedup {
awk '! x[$0]++' $@
}
# removes $HISTIGNORE commands from input
function remove_histignore {
if [ -n "$HISTIGNORE" ]; then
# replace : with |, then * with .*
local IGNORE_PAT=`echo "$HISTIGNORE" | sed s/\:/\|/g | sed s/\*/\.\*/g`
# negated grep removes matches
grep -vx "$IGNORE_PAT" $@
else
cat $@
fi
}
# clean up the history file by remove duplicates and commands matching
# $HISTIGNORE entries
function history_cleanup {
local HISTFILE_SRC=~/.bash_history
local HISTFILE_DST=/tmp/.$USER.bash_history.clean
if [ -f $HISTFILE_SRC ]; then
\cp $HISTFILE_SRC $HISTFILE_SRC.backup
dedup $HISTFILE_SRC | remove_histignore >| $HISTFILE_DST
\mv $HISTFILE_DST $HISTFILE_SRC
chmod go-r $HISTFILE_SRC
history -c
history -r
fi
}
これを行うためのよりエレガントな方法を聞きたいです。
注: HISTTIMEFORMAT を使用して履歴のタイムスタンプを有効にすると、スクリプトは機能しません。
Bash は次の方法で状況を改善できます。
history -a
最後の履歴だけでなく、メモリ内の履歴と一致しない場合にのみ新しいデータを書き込むように修正しました。
erasedups
設定が setの場合、ファイルの読み取り時に履歴を重複排除します。history -w
上記のばかげたスクリプトの代わりに、新しい端末で単純に履歴ファイルをクリーンアップします。