Bashでhistappendがoffに設定されている場合、履歴を上書きするのではなく追加するのはなぜですか?

Bashでhistappendがoffに設定されている場合、履歴を上書きするのではなく追加するのはなぜですか?

数日前、ssh他の端末タブがローカルで多くの操作を実行している間に、1つの端末タブが実行されました。その後、MavericksがインストールされているMac上でコンピュータを再起動しました。

端末をもう一度実行してみると、2番目のタブのコマンド履歴がすべて消えたことがわかりました。注文のみありますssh

だから私はどういうわけかレコードを「マージ」する方法を検索し、レコードが「上書き」ではなく追加されるようにファイルshopt -s histappendで作業を行う必要があることに気づきました~/.bashrc。私たちは、あるレコードセットが別のレコードを上書きしたくありません。追加したいです。

ところでshoptOSにhistappend行ってみると命令を打ってand命令を見ました。echo abcecho defhistoryecho abcecho def

その後、VirtualBoxでUbuntu 2014-10を実行し、同様のことをしましたが、まだ記録された履歴を見ました(shopt -u histappend最初に両方のBashを実行してオプションをオフに設定しました)。

それでは、これを行うメカニズムは正確に何ですか?もしそうなら、histappendオン、オフ、または関係なく、何の意味はありませんか?

shopt -s histappendまた、私の端末をコメントアウトし.bashrcて再起動してからもう一度試しましたが、両方のタブを組み合わせることができたレコードを見ました...確かに奇妙な動作です。原因は何ですか?

答え1

@デビッドこのbash-helpスレッドについて言ったことは正しいです。

ここbashCの関連コードです。

if (history_lines_this_session <= where_history () || force_append_history)
  {
    result = append_history (history_lines_this_session, hf);
    history_lines_in_file += history_lines_this_session;
  }
else
  {
    result = write_history (hf);
    history_lines_in_file = history_lines_this_session;
  }

shopt -s histappendforce_append_history0以外の値()に設定しますtrue

history_lines_this_sessionbashこの対話型セッションで入力したコマンドの数。 Bashを初めて起動すると0です。Enter履歴に保存されている各コマンドに対して1ずつインクリメントします。

where_history()インデックス 0 から始まるメモリ内履歴リストのインデックスです。履歴に書き込まれる次のインデックスを指します。たとえば、履歴レコードが0の場合、インデックスは0になります。 6行の履歴があるとインデックス6になります。

初めて起動して履歴がbashある場合は増加しますが、制限されます。したがって、最大値があります。HISTFILEwhere_history()<= HISTSIZEwhere_history()HISTSIZE

読んだ後は増加しますが、HISTFILEまだゼロです。コマンド番号を実行すると(最大値があるため)。このとき閉じると記録が上書きされます。where_history()history_lines_this_sessionEnter HISTSIZE + 1history_lines_this_session == HISTSIZE + 1where_history() == HISTSIZE(history_lines_this_session <= where_history()) == falsehistappend

自分でテストしてみてくださいbash。オフにすると、一度実行したコマンドの数が1つをhistappend超えて上書きされます。テストが機能するには、他のコマンドが履歴を妨げないことを確認する必要があります(macOSで発生)。履歴を台無しにする可能性のあるコマンドをオフにするには、次のコマンドを使用します。HISTSIZE + 1history_lines_this_sessionwhere_history()HISTFILE

trap - EXIT
PROMPT_COMMAND=
SHELL_SESSION_HISTORY=0 # for macOS only

答え2

histappend私はこれが次のためのものだと信じています一つ端末。

新しい端末で次のことを試してください。

shopt -s histappend
export HISTSIZE=1
export HISTFILESIZE=500

その後、端末を閉じます。これにより、履歴ファイルにexport HISTFILESIZE=50入力したばかりの「」に含まれる最後の499個の最後のコマンドがどのように含まれているかを確認できます。記録が追加された後、500に切り捨てられました。

それでは、別の新しい端末でこれを試してみてください。

shopt -u histappend
export HISTIZE=1
export HISTFILESIZE=500

端末をもう一度閉じます。これで、端末に「export HISTFILESIZE=500」というコマンドが1つしかないことがわかります。

トリックは、そうでない場合、histappend現在の端末履歴(コマンド)にある内容で記録ファイルを上書きすることです。

HISTFILE=の場合、動作に気付かない可能性がありますHISTFILESIZE。しかし、複数の端末で作業することとは何の関係もないと思います。これは別のものとして管理する必要があります...

関連情報