PowerShell
コンソールを触っていると、履歴を取得するGet-History
コマンドではセッション中の履歴しか取得できないが、UpArrowキー
、DownArrowキー
では現在のセッション以前に入力したコマンド履歴が選択できる事に気が付き、これはどういう事? といった疑問を持つかと思います。
これはPowerShell
では入力履歴を提供する仕組みが下記の2系統存在しているためです。
- PowerShell組み込みの入力履歴管理(現在のセッション履歴のみ)
- PSReadlineモジュールによる入力履歴管理(セッション関係なし)(Windows PowerShell v5.0から標準提供)
上記の違いがそれぞれの系統であり、またPSReadline
はWindows PowerShell v5.0以降に標準提供されるため、Windows PowerShell v5.0
以降では下記のようになっています。
Get-History
コマンドレットはPowerShell組み込みの入力履歴管理に属しており、こちらは現在のセッション中の入力履歴のみを移動できる。
UpArrowキー
、DownArrowキー
で移動できる入力履歴はPSReadline
で提供される物になり、こちらは現在のセッションだけではなくそれ以前の入力履歴も参照できます。
PSReadlineについて
PowerShellコンソール
をカスタマイズするPowerShell
モジュールとなり、元々はOSSとして提供されていましたが。Windows PowerShell v5.0
からPowreSehll
の標準インストールに組み込まれているモジュールとなります。
PSreadline
は今回話しをする入力履歴だけではなく、キーバンド設定だったり、構文の色分けだったり多種な機能を提供するモジュールになります。
今回使用している環境
- PowerSehll 7.3.0-preview.1
- PSReadLine 2.2.0 beta4
ドキュメント
入力履歴については、ドキュメントのabout_History
に記載されているのてこちらが参考になります。
PowerShell組み込みの入力履歴管理
ドキュメントに記載がある通り、組み込みの入力履歴管理コマンドでは、現在のセッションで使用したコマンドだけが追跡され。セッションが終了すると削除されます。
- Add-History コマンドの履歴にコマンドを追加する。Get-Hisotryで取得できる、HistoryInfoのオブジェクトでインプットできる
- Clear-History コマンドの履歴からコマンドを削除する
- Get-History コマンドの履歴を取得する
- Invoke-History コマンドの履歴からコマンドを実行する
今現在も上記のコマンドレットは利用できますが、基本的にはPSReadline
の履歴管理を使う形になります。
PSReadLineの入力履歴管理
ドキュメントに記載があるように、UpArrowキー
やDownArrowキー
などのキー操作で以前の入力履歴を選択できる機能をPSReadline
モジュールでは提供しています。
PSReadline
ではカスタムキーバインドを設定する機能も提供しており、入力履歴の操作もこれを利用して設定されています。
今現在、PSReadline
のデフォルトでは、emacs
モードで下記履歴機能が提供されています。
- <`UpArrowキー`> PreviousHistory
- <`DownArrowキー`> NextHistory
- <`Ctrl+r`> ReverseSearchHistory
- <`Ctrl+s`> ForwardSearchHistory
- <`Alt+F7`> ClearHistory 現在のセッション中のみで利用する履歴をクリアするだけで、historysavepathに格納されている履歴がクリアされるわけではない。
- <`Alt+>`> EndOfHistory 入力履歴の最後の項目に移動
カスタムキーバインドについては、そもそもPSReadline
ではemacsモードとviモードで違いが出てきたりするので細かいことはドキュメントを確認してください。
PSReadlineの入力履歴保存場所
コマンドの入力履歴がどこで管理されているかについては上記ドキュメントに記載があります。
Windows環境では
- $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine
Windows以外の環境では以下のいずれかに格納されます。
- $env:XDG_DATA_HOME/powershell/PSReadLine
- $env:HOME/.local/share/powershell/PSReadLine
格納場所を確認する方法としては、Get-PSReadLineOption
コマンドレットでPSreadline
の設定を取得でき、設定項目HistorySavePath
が保存場所のパスになります。
PSReadlineの入力の履歴保存場所を変更する
デフォルト以外の場所に入力履歴保存場所を変更した場合は、Set-PSReadLineOption
コマンドレットのHistorySavePath
オプションを利用して変更することができます。
ただしこの設定は現在のセッションのみ有効となるため、永続的に設定するためには起動プロファイル $profile で取得できるファイルにコマンドを追記して下さい
# 現在のセッションのみ有効。永続的に変更する場合は起動プロファイルに追加
Set-PSReadLineOption -HistorySavePath <<保存場所のパス>>
PSReadlineをRemove-Moduleして履歴が利用できなくなる事を確認してみる。
PSReadline
といわれてピンとこない場合は、機能削除してどう変わるか見るのが早いと思います。
現在のセッションから読み込んでいるPowerShell
モジュールを削除するコマンドを実行して、PSReadline
を機能しないようにして履歴管理がどうなるか確認してみます。
なおRemove-Module
は現在のセッションから削除するだけので、コンソールを開き直せば元に戻ります。
Remove-Module PSReadLine
# oh-my-posh を利用している場合はそちらもremove-module
Remove-Module oh-my-posh
Remove-Moudle
をする事で入力履歴がPowerShell
組み込みだけの利用となり、
UpArrowキー
、DownArrowキー
で提供される入力履歴もセッション中に入力した物だけになる事が確認できると思います。
総評
今現在となっては、組み込みで用意されている履歴管理を使う機会はほぼないかとは思いますが。
歴史的経緯からPowerShellでは履歴管理が2系統あるといった事だけは理解しておいた方がいいかと思います。