Bashがまだ重複した行を削除して保持するのはなぜですか?

Bashがまだ重複した行を削除して保持するのはなぜですか?

私の~/.bashrcには次の行があります。

export HISTCONTROL=ignoreboth:erasedups

ただし、実行するたびに、次のようなsomecommand冗長コマンドが追加されます。.bash_history

grep -w somecommand ~/.bash_history
somecommand
somecommand abc xyz
somecommand 123
somecommand
...

なぜこれが起こり、どのように予防できますか?

答え1

このerasedupsオプションは、次の2つの条件に基づいて重複行を削除します。

  • この行はリストから削除されます。メモリ
  • 新しいコマンドがリストに追加された場合にのみ適用されます。

メモリ内のリストが出力ですhistory。 Bashが閉じられると、
「メモリ内の」リスト全体がファイルに書き込まれます(histappendが設定されていない場合)。history -w

したがって、メモリ内のリストが次のような場合:

$ history
1  cmd1
2  cmd2
3  cmd3
4  cmd1
5  cmd2
6  export HISTCONTROL=ignoreboth:erasedups
7  history

それは次のとおりです。

$ history
1  cmd2
2  cmd3
3  cmd2
4  export HISTCONTROL=ignoreboth:erasedups
5  cmd1
6  history

すべてのcmd1コマンド(追加されたコマンドを除く)が削除されます。

実行すると、cmd2すべての重複エントリがcmd2削除されます(また)history

$ cmd2
$ history
1  cmd3
2  export HISTCONTROL=ignoreboth:erasedups
3  cmd1
4  cmd2
5  history

しかし、今でもファイルは~/.bash_history変更されていません。前のセッションのコマンドのリストがまだ含まれています。ファイルにgrepを使用すると、使用したコマンド(cmd1とcmd2)を含む多くの重複エントリ(dups)が表示されることがあります。 grep はメモリ内リストでのみ正しく動作します。

$ history | grep cmd1

リストがファイルに書き込まれると(history -w)、grepを使用すると、セッションで使用されている各コマンドラインの1つのインスタンスのみが検索されます。

次のコマンドを使用して、毎回ディスクファイルを強制的に更新できます。

$ PROMPT_COMMAND='history -w'

答え2

によるとman bash

無視された値のため、前の履歴エントリと一致する行は保存されません。

somecommand引数なしで連続して2回実行すると、次の結果のみが表示されます。続けて入り口。

同様にsomecommand 123、2回連続して実行すると、履歴に1回だけ追加されます。

リストのコマンドに no が表示されます。続けて複製されたため、この機能は期待どおりに機能します。

答え3

それぞれの新しいコマンドを一意に記録するのは難しいです。まず、次のものを追加するか、類似する必要があります ~/.profile

HISTCONTROL=erasedups
PROMPT_COMMAND='history -w'

次に、以下を追加する必要があります~/.bash_logout

history -a
history -w

関連情報