Rust製bash互換シェルbrush v0.4が示す本気度
Rustで書かれたbash/POSIX互換シェル「brush」のv0.4.0が公開された。200超のプルリクエストを束ね、set -eやpipefailが本物のbash挙動になり、macOSログインシェルにも据えられる。本気の到達点だ。
Rustで書かれたbash/POSIX互換シェル「brush」のv0.4.0が公開された。200超のプルリクエストを束ね、set -eやpipefailが本物のbash挙動になり、macOSログインシェルにも据えられる。本気の到達点だ。
「Bourne Rusty Shell」、200超のPRを束ねて出てきた
brushの開発者であるリューベン・オリンスキー氏(Reuben Olinsky、@reubeno)が、現地時間2026年5月3日にbrush v0.4.0を公開した。リポジトリのリリースノートによると、このバージョンは数か月の作業と 200本超 のマージ済みプルリクエスト(pull request)を束ねた、文字通りの大型リリースだ。
brushは「Bo(u)rn(e) RUsty SHell」、つまりBourne系シェルをRustで書き直したものだ。bashで動いている既存のスクリプトや.bashrcをそのまま動かすことを目標に、シンタックスハイライトと履歴ベースの自動サジェストを最初から内蔵している。執筆時点でGitHubのスター数は約1,500、Homebrew・Arch Linuxの公式リポジトリ・cratesにすでに登録されており、daily driverとして使えると開発者自身が宣言する段階に来ている。
Rust製シェルというくくりで言えば、brushは決して一番手ではない。先行するnushellは構造化データを軸に独自路線を行き、fishは4.0でC++からRustへ書き直された。ただし、これらはいずれも「bashとは違うもの」を作る方向に舵を切っている。bash互換そのものをRustで再実装するという、もっとも保守的で、もっとも面倒な道を選んだのがbrushだ。
brushはbashの代替を狙うのではなく、bashそのものとして振る舞うシェルを目指している。だからこそ、200本のプルリクエストの大半は派手な新機能ではなく、bashの細かな挙動をなぞる地道な作業に費やされている。
bashの「あの挙動」が、ようやく本物になった
このリリースの中心は、bash互換性の底上げだ。これまでbrushでは限定的にしか効かなかったオプション群が、ようやくbash本来の意味で動くようになった。
具体的には、set -e(errexit)とpipefail、set -u(nounset)、そしてfailglob。これらはシェルスクリプトの 基本のエラー検出オプション で、有効になれば未設定変数の参照や失敗したコマンドが即座にエラーとして浮き上がる。さらにERRトラップが実装され、-c実行時にもEXITトラップが正しく発火するようになった。コプロセス(coproc)も、構文解析と実行の両方が動く。
注意点: v0.3.0までのbrushは、これらのオプションが「書けるが効かない」状態だった。v0.4.0からは本物のbashと同じ厳しさで動く。つまり、これまで気づかずに通っていたエラーが、突然スクリプトを止め始める可能性がある。これは設計上の意図であり、開発者は「bashとの挙動の差を見つけたらissueを上げてほしい」と呼びかけている。
ヘッドラインの裏で進んでいるのは、もっと細かい補修作業だ。算術演算では高基数リテラル、忠実なオーバーフロー/アンダーフロー、レガシーな$[expr]構文、そして|=と^=の代入演算子。ヒアドキュメントはコマンド置換やクオート文脈での挙動が大きく改善され、ビルトインではcallerが新規追加、readがほぼフィーチャーコンプリートになった。mapfile -O、getoptsのOPTERR、compgen -Aのbinding/command/予約語補完、printf %qの空文字列クオートまで、リリースノートが列挙する変更は数十項目に及ぶ。
これらの一つひとつは、知っている人だけが「ああ、それは助かる」と頷く類の修正だ。しかし、こうした細かな互換性の積み重ねこそが、シェルが「実用」と呼ばれる領域に入るための条件でもある。
プラットフォーム対応の広がり、地味だが効く
機能の話ばかりが目立つが、このリリースで個人的に重要だと思っている変更がもう一つある。macOSのログインシェル化が解禁された点だ。
これまでbrushはmacOSで起動時にハングする問題を抱えており、chshでログインシェルに設定するのは現実的ではなかった。v0.4.0でこの問題が修正され、開発者は「Macでbrushをログインシェルにしたい人は試してほしい」と書いている。一見ささやかな変更だが、シェルが日常使いの環境に組み込まれるかどうかは、ログインシェルに据えられるかどうかと深く結びついている。これがクリアできた意味は小さくない。
Windowsでもパス処理が大幅に改善され、/dev/nullの適切なエミュレーション、CIでのWindowsテストスイートの実行が始まった。FreeBSDのビルドが復活し、Androidと32ビットターゲットもクリーンにビルドできるようになった。WebAssembly側では、split_pathsがWASMで安全に動くようになり、wasm32-wasip2の基本的なスモークテストがCIで回り始めている。
「Windowsサポートは依然として実験的な状態だが、このサイクルで意味のある形で成熟した。以前brushをWindowsで試したことがあるなら、もう一度触ってみてほしい時期だ」(リリースノートより意訳)
インタラクティブシェルとしての顔も整えてきた
brushはスクリプト実行エンジンであるだけでなく、対話型シェルでもある。v0.4.0では、こちらの顔も少しずつ整ってきた。
新たに導入されたのは、TOML設定ファイルのサポートだ。~/.config/brush/config.tomlにbrush固有の設定を書ける。シェルスクリプトベースの設定とは別レイヤーで、起動時の挙動や実験的機能のトグルを管理できる。これは現状実験的位置づけだが、.bashrcを継承しつつbrush特有の設定を分離するという発想自体が、bashの拡張ではなく後継として設計されている証だ。
zshスタイルのpreexec/precmdフックも追加された。プロンプトフレームワークやコマンド実行時間の計測、starshipやatuinといった外部ツールとの連携で使われるものだ。これらが動くということは、現代的なシェル環境の エコシステムに直接乗れる ことを意味する。
ターミナル統合の方向では、セマンティックなプロンプトとコマンドのマーキング機能が実験的に入った。VS CodeのターミナルやWeztermのような最新ターミナルが提供する、コマンド単位のナビゲーションや終了ステータス表示と連動するための仕組みだ。リードラインマクロの初期サポートも入り、補完まわりではファイル名のスペース・特殊文字エスケープ、mark-directories、COMP_KEY/COMP_TYPEの母数化など、「壊れていることに気づかないと気づかない」類の修正が積み重なっている。
組み込み利用者向けのAPI整備、そして未来への布石
brushはバイナリのシェルであると同時に、Rustクレートとしても公開されている。brush-core、brush-parserをライブラリとして使い、自前のアプリにシェル機能を埋め込みたい人々がいる。v0.4.0は、こうしたembedder向けにもいくつかの大きな変更を入れた。
最大の変更は、Shell型がShellExtensionsという型パラメータでジェネリックになったことだ。これによって、組み込み利用者は独自のビルトインや変数挙動、その他のフックを、フォークせずに追加できるようになる。既存のShell型を直接参照していたコードは、具体的な拡張型を選ぶか、ジェネリックを通す必要がある。
AST(抽象構文木)とシェル状態の両方でserdeサポートが追加された。これにより、初期化のメモ化やシェル状態のスナップショット保存といった、これまで難しかったユースケースが視野に入る。そして、現行のPEGパーサに加えて、winnowベースの新パーサのスキャフォールディングが入った。PEGパーサは引き続き本番のパーサだが、winnow側は将来的により高速で診断しやすい代替を目指す土台だ。MSRVはRust 1.88に引き上げられ、ビルドやテストのスクリプトはcargo xtaskサブコマンドへ整理された。
これらは派手さこそないが、プロジェクトが「単発の趣味実装」ではなく、長期的に育てる対象として設計されていることを示している。
bash互換という「割に合わない」道を選ぶこと
brushの仕事を見ていると、bashという存在の重さが改めて分かる。fishやnushellのように「bashとは違うもの」を作るほうが、設計の自由度は圧倒的に高い。bash互換を選ぶ瞬間、開発者は何十年分もの仕様の癖、エッジケース、歴史的経緯のすべてを背負い込むことになる。
それでもこの道を選ぶ理由があるとすれば、世の中に存在する膨大なシェルスクリプト、.bashrc、ビルドシステム、CIパイプライン、それらすべてをそのまま走らせたいという需要が消えないからだ。bashの代替が必要なのではなく、メモリ安全なbash再実装 への需要がある。OSHもその系譜にあり、brushはその挑戦者がさらに増えたことを意味する。
リリースノートの末尾には、貢献者への謝辞が並んでいる。@lu-zero氏のパーサ近代化への継続的な取り組み、@Elsie19氏のbash互換修正、@oech3氏のエッジケーステスト、@StudioLE氏のヒアドキュメントとトークナイザー修正、そして@takeshiD氏と@xtqqczze氏の継続的なコントリビューション。個人プロジェクトとして始まったものが、bashという巨象に挑むコミュニティへと育ちつつある。
bashを置き換えるのではなく、bashそのものになろうとする。誰かがやらなければならない仕事を、reubeno氏とコミュニティは選んでいる。
参照元
関連記事
- 3Dグラフィックスが走るターミナル「Ratty」
- GitHub CLIがテレメトリ収集を開始、デフォルト有効
- Rust Coreutils 0.8が登場、dd 45%高速化とブラウザ実行環境
- RustとAIで一からX11サーバーを書き直す。yserverが問いかけるもの
- RustベースOS「Redox OS」に5月の大型進捗、Xfce移植とファイルシステム高速化が同時到達
- WindowsでLinuxコマンドがネイティブに動く時代
- LinuxカーネルにRust開発者が足りない
- マイクロソフトが警告。PyPI mistralai汚染、import時に全消去の罠
- RPCS3が「コードを学べ」、AIエージェント締め出しへ
- Zed 1.0公開、Atom開発者の5年越しの再挑戦