端末アプリで複数のタブを開いたり、byobu(tmux・screen)で複数の端末を開いたりした場合に、各端末で動くBashのコマンド履歴を「共有化」する方法を紹介します。
端末ごとにコマンド履歴が分離する問題
複数の端末を同時に開くと、Bashのコマンド履歴は別々に保持されます。「端末A」で実行したコマンドは、「端末B」のコマンド履歴には入りません。
さらに、それぞれが終了時に「~/.bash_history」に書き込むため、最後に終了した端末のコマンド履歴だけしかコマンド履歴ファイルに残らない、という問題もあります。
コマンド履歴を「共有」する方法
この問題は、各端末で同時に動いているBashでコマンド履歴を「共有化」することにより、解決できます。
そのためには、次の内容を~/.bashrcに追記します。
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
shopt -u histappend
これにより、コマンドが終了してプロンプトが再表示されるごとに、コマンド履歴の保存、消去、再読込が行われるようになります。
その結果、別の端末で実行された履歴もhistoryコマンドで参照できたり、↑(上矢印キー)で呼び出せたり、Ctrl+Rによるコマンド履歴検索(リバースインクリメンタルサーチ)できたりするようになります。
ただし、マシンスペックとHISTSIZEやHISTFILESIZEの上限の兼ね合いによっては、プロンプト再表示に時間がかかるようになることもあるため注意が必要です。
なお環境変数「PROMPT_COMMAND」は、プロンプトが表示される時に実行するコマンドを設定するものです。上記の設定で、この環境変数「PROMPT_COMMAND」に設定されている各コマンドの処理内容は以下の通りです。
「history -a」は、実行しているBashセッションのコマンド履歴を~/.bash_profileに追記します。
「history -c」は、実行しているBashセッションがメモリ上に持っているコマンド履歴を消去します。
「history -r」は、~/.bash_profileからコマンド履歴を読み込んで、実行しているBashセッションのコマンド履歴に設定します。
最後に「$PROMPT_COMMAND」を記述しているのは、別の行で別のコマンドを環境変数「PROMPT_COMMAND」に設定済みだった場合、上記の処理が終わってから実行するためです。
「shopt -u histappend」は、シェルのオプション指定「histappend(終了時にコマンド履歴を~/.bash_historyに保存する)」を無効化しています。これは、PROMPT_COMMANDを上の通り設定してプロンプトを再表示するたびに保存している場合、終了時の保存は必要がないためです。
こうした設定により、別の端末で動くBashのコマンド履歴も使えるようになります。ただし、読み込まれるのは「プロンプトを再出力する前」なので、プロンプトの表示後、他のBashに入力されたコマンド文は履歴として参照できません。参照したい場合、何も入力せずに「Enter」キーを押すか、「Ctrl+C」キーでプロンプトを再出力します。すると、最新のコマンド履歴が読み込まれます。
関連項目
コメント