Yash 2 その 98: 履歴ファイルの新しい形式と共有
さらに考え深めるうちに、色色面倒くさい事実に気付く。
コマンド履歴に入っている各コマンドは番号で管理するのだが、複数のシェルプロセスで同じ履歴を共有するということは、コマンドの番号もすべて共有するということになる。しかも、単純に一から順番に番号を振ってゆくのでは番号が永久に大きくなっていってしまうので、シェルを新しく起動したときには番号を振り直すようにしたい。とはいえ、既にシェルが起動している状態で別のシェルプロセスを起動したときにも番号を振り直してしまうと、元元起動していたシェルで勝手に番号が変わって紛らわしいのでそれは避けたい。ということで、どこかうまいタイミングで番号を振り直したいのだが、どうすればよいか。
一番の問題は、プロセス間通信である。シェルが起動したときに、他にシェルが起動していないことをどのようにして知るか。あるいは、複数のシェルプロセスが同じ履歴ファイルを共有していることをどのようにして知るか。シェルプロセス間で使える直接的な通信方法が用意されていれば話は簡単なのだが、親子関係にないプロセス同士で通信を行う方法は POSIX 規格の範囲内ではとても限られている。結局、適当にファイルをロックしつつ、共有したいデータ内容を履歴ファイルに直接書き込むという原始的な方法を取らざるを得ない。
こうなると、まず、履歴ファイルの形式を変える必要が出てくる。これまでの yash の履歴ファイルは、コマンドの内容をそのまま一行づつ書き出した単純なテクストファイルだった (すなわち、bash が用いている readline ライブラリと同じ形式) が、これでは複数のシェルプロセス間で履歴の番号を共有することさえできない。これまでは readline ライブラリとの互換性を考えてこの形式を用いていたが、今回はもう踏ん切りをつけて、独自の形式にする。(とはいえ、ksh のようにバイナリ形式にすることはしない)
また従来は履歴ファイルへの書き込みはシェルが終了するときに纏めて行っていたが、これでは履歴の共有はできないので、コマンドを実行する度に毎回履歴ファイルに書き込むとともに、他のシェルプロセスが書き込んだコマンドをファイルから読み込む必要がある。その為、ファイルへの書き込みは原則として末尾への追記のみに限る。こうすれば、他のプロセスが書き加えた部分がすぐに分かるので、それを読み込むのが楽にできる。尤も、追記するばかりではどんどんファイルが大きくなってしまうので、これもうまいタイミングで内容を削らなければならない。どのようにして削るかと削ったことをどのようにして他のプロセスに知らせるかは、これから検討すべきことである。
そして他のシェルが起動していないことをどうやって知るかだが、これは各シェルプロセスが自身のプロセス番号を履歴ファイル内で申告することで行うこととする。すなわち、シェルは起動時に自身のプロセス番号を履歴ファイルに書き込むとともに、他のプロセス番号が書かれていないかを調べる。そして終了時に自身のプロセス番号をファイルから抹消する。これにより、自分以外のシェルプロセスが同じ履歴ファイルを共有しているかどうかを知ることができる。
因みに、このようにうまいタイミングで番号を振り直すことは POSIX 規格で強制されている。
The command history list shall reference commands by number. The first number in the list is selected arbitrarily. The relationship of a number to its command shall not change except when the user logs in and no other process is accessing the list, at which time the system may reset the numbering to start the oldest retained command at another number (usually 1). When the number reaches an implementation-defined upper limit, which shall be no smaller than the value in HISTSIZE or 32767 (whichever is greater), the shell may wrap the numbers, starting the next command with a lower number (usually 1).
正直なところ、この強制はハードルが高すぎるのではないか。
| 固定リンク
コメント