コマンドラインヒストリ

rcを使っていて,戸惑うのがコマンドラインヒストリがないこと.
正確にはヒストリがないのではなく,シェルの機能ではなく,ウィンドウシステム(rio)の機能であるという点が,UNIXと違う.(カレント)ウィンドウに表示された内容は/dev/textに残っているから,これからgrepせよというのが,Plan9流の考えだ./dev/textはrioが提供する(デバイス)ファイルである.ちなみにacmeの場合は,/mnt/acme/acme/bodyになる(末尾のスクリプトでは,/dev/textにbindしている).

スクリプトを書くとこんな感じ.先人に倣って " という名前のスクリプトにしておく." を実行すると最後に実行された5つのコマンドが表示され," mk と実行すると,mk から始まるコマンド履歴が表示される.PROMPT変数は各自の環境に合わせる必要がある.

#!/bin/rc
rfork en

if (test -r /mnt/acme/acme/body)
	bind /mnt/acme/acme/body /dev/text

switch ($service) {
case terminal
	PROMPT='term% '
case cpu
	PROMPT='cpu% '
}

fn cmds {
	grep '^'$PROMPT /dev/text | sed 's/^/  /'
}

switch ($#*) {
case 0
	cmds | tail -5
case *
	cmds | grep '^  '$PROMPT^$"*
}

ちなみに,history(1)があるが,これはファイルの履歴(/n/dump/YYYY/MMDD/...)を表示するコマンドである.

(追記:2006-09-01)スクリプトの冒頭の"rfork en"はrcの組込みコマンドである.意味はシステムコールのrfork(RFNAMEG|RFENVG)と同じで,子プロセスを作るときに,名前空間環境変数は親プロセスと共有するのではなく,コピーして子プロセス独自のものを用意する.これはスクリプトの副作用(名前空間の汚染?)をrcに残さないための常套句である.