再帰globパターン **/ の元祖は zsh なのか、調べてみた
今日 @satoh_fumiyasu さんのこんなツイートを見かけました。
zsh や rsync にある拡張 glob pattern のひとつ、** の元祖ってどこ?
— ふみやす@シェルまおう(自称ではない) (@satoh_fumiyasu) 2016, 2月 10
私もずっと気になっていたので、この機会に調べてみました。
最初は ..../ だった!
当時のソース公開は usenet 経由だったよな、というわけで groups.google.com で zsh を検索すると、Zsh-1.0 の公開時のアナウンス と、 ソース が出てきました。
アナウンスの中では zsh の機能の由来を From ksh, From tcsh, From bash と細かく挙げているのですが、 再帰globパターンは『その他』として別扱いされています。
Other stuff: - recursive directory search in filename generation (for example, "ls ..../*.c" lists all .c files in the hierarchy)
これによると Zsh-1.0 では、 **/
のような再帰 glob を ..../
と書いていたのですね。
この書き方は翌年リリースされた Zsh-2.00 でも変わらないようです。
Zsh-2.1 で ****/ に変わった
Zsh-2.1 の README の
Modification history に、初めて ****/
の言及が出てきます。
Modification history: 0.03-1.0: - "..../" is now "****/". I know this isn't backward compatible, but I had no choice; the string "..../" was unquotable.
0.03-1.0 とありますが、恐らく 2.03 から 2.1 のことを指しているのでしょう。
Zsh-2.2 で **/ になった
そしてついに Zsh-2.2 の
Modification history に、 **/
が出現します。
Modification history: 2.2.0-2.1.0: o ls **/file is now equivalent to ls ****/file
時に、1992/05/14。 ここまでの経緯を見るに、zsh が元祖ではないか?と私には見えました。
なぜ ..../ や ****/ だったのか?
ところでなぜ最初、再帰glob は ..../
という長い書き方だったのでしょう? それは、どうやら、
実装に理由があったようです。
そもそも zsh の **/
は、0個以上へのマッチ文字 #
(正規表現のクリーネスターに相当)を使った書き方 (*/)#
の省略形です。
(マニュアルを参照)
で、なんと、Zsh-1.0 のソースを読むと、 ..../
を直接 (*/)#
へと置き換える^^、という実装になっていたのです。
要するに、5文字で、ファイル名として滅多に使わないものという制約の中で、打ちやすいものを選んだのでしょうね。