窓辺の小石 第104回 危険な「過去」への旅
コンピュータでは、同じ処理を繰り返し行なうことがある。コマンドラインには「ヒストリ」あるいは「履歴」と呼ばれる機能があり、過去に実行したコマンドラインを呼び出して実行できる。
シェルの履歴機能は、BSD系Unixに搭載されていたcsh(C shell)が最初の実装とされる。cshの作者Bill Joyの「An Introduction to the C shell」によれば、履歴機構はInterlispのREDOから着想を得たらしい。Interlispのマニュアルを見ると「REDO -1」で直前のイベントを再実行できたようだ。
cshの履歴機能では、「!-1」とすれば、実行前に1つ前のコマンドに置換される。これには、「!!」という略記方法があった。また、「!*」は、直前のコマンドラインからコマンド名を抜いたすべての引数に置換される。たとえば、「vi ~/test.c」として編集を行なったあと、「cc !*」で「cc ~/test.c」を実行することができた。
履歴展開は、コマンドライン内で「イベント指示子[[":"]単語指示子[":"修飾子]]」という書式を使う。イベント指示子は、“!”で始まる履歴番号や“^”で始まる履歴検索など、特定の履歴(イベント)を指定するものだ。後続する単語指示子は、選択された履歴の中から特定の単語を抜き出すための指定、修飾子は履歴展開の動作を変更させるもの。前述の「!*」では、「!」が直前の履歴を指定する「履歴指定子」で、「*」が単語指示子である。修飾子は、たとえば「!-1:1:t」とすると、直前のコマンド(!-1。これが履歴指定子)の最初の引数(1。同単語指示子)のファイル名部分(t。これが修飾子)を取り出したものになる(写真01)。
写真01: bashの履歴展開は、!を使い、コマンドの指定、引数の取り出し、動作指定を行なうことができる。「修飾子」としてpを使うと履歴展開だけを行ない、コマンドを実行しないが、履歴には入るため、!!で実行することができる。このように最小のキー入力で履歴を使うことが可能だ
この修飾子に“p”を使うと、履歴展開は行なわれて表示されるが、実行は行なわれない。ただし履歴展開された結果が履歴に入るので、“!!”で実行させることができる。
1980年台、cshはファイル名補完と履歴展開で使いやすさはピカ一であった。cshを使ったあとMS-DOSを使うと履歴機能が貧弱でかなりイライラした記憶がある。当時のMS-DOSは直前のコマンドしか呼び出すことができなかった。本格的なヒストリ機能は1991年のMS-DOS 5.0に搭載されたDOSKEYで実現された。
その後、さまざまなシェルが作られたが、どれも履歴機能を採用し、コマンドラインの編集や履歴の呼び出し機能が作られた。
“!!”による履歴展開は便利でいまだに利用頻度が高い。たとえば、パッケージマネージャーのキャッシュ更新“apt update”などはsudoが必要だ。 “apt update”が失敗したあと“sudo !!”とすればよく、履歴を呼び出して編集するよりも簡単だ。
○PowerShellとbashの履歴機能
PowerShellにも履歴機能がある。(表01)にPowerShell(Ver.7.2.2)とbash(Ver.5.0.17)の履歴機能比較を示す。PowerShellにもPSreadlineを使ったカーソルキーによる履歴呼び出しや、履歴の取得コマンド(Get-History)など、基本的なところは、bashなどと同じだが、大きく違うのは、bashにある'履歴展開の機能がないことだ。
bashでは、readlineの関数を使って履歴に対して検索もできる。キー割り当ては、「bind -p | grep 'hist'」で調べることができる。Ctrl+Rを使うと履歴のインクリメンタル検索が可能だ。
PowerShell 7.3.3では、コマンドラインの入力で、自動的に後方インクリメンタル検索が行なわれ、グレーの文字でコマンドラインに履歴が表示される(写真02)。このまま文字を入力していくと、前方一致で履歴が検索される。履歴を確定(選択)するには、カーソルキーの右矢印キーを押す。なお、PowerShellで履歴関連のキー割り当てを調べるには、
get-psreadlinekeyHandler -Bound -Unbound | where group -like 'hist*'
とする。KeyがUnboundとなっているのは、未割り当ての機能である。
写真02: PowerShell 7.3.3では、コマンドライン入力で、自動的に履歴検索が行なわれ、候補がグレー文字で表示される。カーソルキーの右矢印キーを使うことで履歴候補を確定できる
今回のタイトルネタは、米国のSFテレビドラマStar Trekオリジナルシリーズのエピソード「危険な過去への旅」(原題THE CITY ON THE EDGE OF FOREVER)である。いわゆる「歴史改変もの」に分類されるエピソードで履歴(ヒストリ=歴史)に合わせて選んだ。