自作シェルの進捗とBashの細かい話(2024年5月26日)
Sun May 26 10:42:51 JST 2024 (modified: Sun May 26 11:01:27 JST 2024)
views: 1292, keywords:自作シェル, 寿司シェル, sush
前回に引き続き自作シェルの開発が暴走気味なのでドキュメントを残すための記事です。case文のためにBashのグロブの拡張を実装していました。こんな機能、自分では使わないのですが、bash-completionの巨大スクリプトが使ってるので泣きながら実装していました。
で、だいたいできました。たぶん連載で扱うのは2年後でしょうか・・・
実装した拡張グロブ
こんなやつです。たぶん最近のBashだとデフォルトで使えます。以後、こいつらのことを「拡張グロブ」と表記します。
### @()内の|で区切ったひとつのパターンにマッチ ###
case 小山田 in @(五反|山|小山)田) echo マッチ ;; *) echo マッチせず ;; esac
$
マッチ### @()内の|で区切ったひとつのパターンに0回か1回マッチ ###
case 田 in ?(五反|山|小山)田) echo マッチ ;; *) echo マッチせず ;; esac
$
マッチ### !()内の|で区切ったひとつのパターンにマッチするとアンマッチ ###
case 小山田 in !(五反|山|小山)田) echo マッチ ;; *) echo マッチせず ;; esac
$
マッチせず# 注意: これは「山小小小」が!(山)とマッチ(山とアンマッチ)するのでマッチ
case 山小小小田 in !(山)田) echo マッチ ;; *) echo マッチせず ;; esac
$
マッチ### +()内の|で区切ったひとつのパターンに1つ以上繰り返しでマッチするとマッチ ###
case 上田山田田 in +(山田|上田)田) echo マッチ ;; *) echo マッチせず ;; esac
マッチ### *()内の|で区切ったひとつのパターンに0つ以上繰り返しでマッチするとマッチ ###
case 田 in *(山田|上田)田) echo マッチ ;; *) echo マッチせず ;; esac
$ マッチ
で、寿司シェルのmainブランチにも同じものが実装されています。バグがなければいいなあ・・・(あれば指摘は大歓迎です)。
現時点でのマッチングの処理は、ココにありますが、まだ整理していません。
今後
パーサーの側では、@( )
などの文字列を引数にしてもエラーがで出ないように、いろいろコードを追加しました。次のようにブレース展開とかもできます。
### 寿司シェルでの例 ###
echo @({あいう,えお}|{AB,CDE})
🍣 @(あいう|AB) @(あいう|CDE) @(えお|AB) @(えお|CDE)
ただ、Bashだとブレース展開後に次のように拡張グロブが機能するのですが、
### Bashの場合 ###
echo /@({b,m})*
$ /bin /boot /media /mnt
寿司シェルでは使っているクレートが拡張グロブに対応しておらず、何も起こりません。
### 寿司シェルの場合 ###
echo /@({b,m})*
🍣 @(b)* /@(m)* /
・・・これは、ファイルグロブを実装しろということでしょうか。ほんとならクレートにコントリビューションすべきではあるけど・・・
現場からは以上です。