Rubish:純粋な Ruby で書かれた Unix シェル

2026/05/23 15:32

Rubish:純粋な Ruby で書かれた Unix シェル

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

Rubish は、Ruby で実装された純粋な UNIX シェルであり、完全な Bash 互換性を備えており、既存の Bash スクリプトをそのまま実行できることを保証します(あらゆる逸脱はバグとして扱われます)。開発者がプロンプト内でブロック、イテレータ、ライブラリ、クラスを通じてシステムコマンドと高レベルの Ruby ロジックを直接組み合わせられるようにすることで、Ruby 統合を深めます。コマンドの実行には Ruby 風のシンタックスが採用されており、条件式は

{ }
内において Ruby 式表現を用い(例:
{ if ... }
)、メソッドは括弧または引数で呼び出せる(例:
ls('-la')
)、パイプラインは自然に連鎖する(例:
ls().sort.uniq()
)、そしてコマンド出力はイテレータ(例:
.each
,
.map
,
.select
,
.detect
)を使用して行ごとに処理されます。大文字で始まる行はインライン Ruby 評価をトリガーし、
Time.now
Dir.glob('*.rb').sort
のような機能をサポートします。Rubish はまた、Ruby 風の関数定義(
def...end
)、カスタムプロンプト、遅いバックグラウンド初期化、および非信用可能なスクリプト用の制限モード(
rubish -r
)をサポートします。Zsh 互換性もほぼ完全であり、
setopt/unsetopt
compdef/compinit
fpath
を通じたオートロード、そして
%X
プロンプトコードを処理します。公開 API(
require 'rubish'
)により Ruby アプリケーションがプロセス内でシェルセッションを駆動でき、フォークと exec のオーバーヘッドなしでシンタックスハイライト、補完、パースを実現します。Rubish は Homebrew(
brew tap amatsuda/rubish && brew install --HEAD rubish
)から即座にインストールでき、ソースからも入手可能です。また、最小経路の Ruby 検出のための Bash ランチャーを含み、インタラクティブモードをサポートし、
/etc/shells
chsh
を通じてシステム全体ログインシェルとして設定できます。

本文

Rubish: 純粋な Ruby による UNIX シェル実装

Ruby VM によって実行され、シェル構文を Ruby コードへコンパイルする、UNIX シェルとしての純粋な Rubyによる実装です。

コンセプト

  • Bash と完全互換: Rubish は Bash の全ての機能をサポートし、既存の Bash スクリプトをそのまま動作させます。動作しないスクリプトはバグですのでご報告ください。
  • 深い Ruby 統合: シェルコマンドと Ruby コードをシームレスに混在させられ、ブロックやライブラリなど Ruby の強力な機能を活用できます。

インストール

Homebrew (macOS)

brew tap amatsuda/rubish
brew install --HEAD rubish

ソースから

git clone https://github.com/amatsuda/rubish.git
cd rubish
bundle install
bundle exec exe/rubish

bin/rubish
は動作可能な Ruby を探索する小さなランチャーです。Bundler が利用できない環境(.app バンドル内や最小限の PATH など)でも使用できます:

./bin/rubish
RUBY=/opt/homebrew/opt/ruby@3.4/bin/ruby ./bin/rubish   # 明示的な上書き

使用方法

  • インタラクティブなシェル:
    rubish
  • シングルコマンド:
    rubish -c 'ls -la'
  • スクリプト実行:
    rubish script.sh
  • ログインシェルとして設定:
    echo "$(which rubish)" | sudo tee -a /etc/shells && chsh -s "$(which rubish)"

Bash 以上の機能

Ruby の条件式

if
while
until
の条件句を
{ }
で囲むことで Ruby 式を使用可能です。

COUNT=5
if { count.to_i > 3 }
  echo 'count is greater than 3'
end

while { count.to_i > 0 }
  echo $COUNT
  COUNT=$((COUNT - 1))
done

Ruby スタイルのメソッド呼び出し

括弧を使用した Ruby 式構文でコマンドを起動できます。

  • ls -la
    ls('-la')
    は同等です。
  • cat(file.txt)
    grep('pattern', file.txt)
    のように引数を渡せます。

メソッドチェーン

Ruby のドット演算子を使用して、コマンドチェーンとパイプラインを形成できます。

# ls | sort.uniq と同等
ls().sort.uniq

# cat file.txt | grep(/error/) と同等
cat(file.txt).grep(/error/)

# ブロックとの組み合わせ
ls.select { it.end_with?('.rb') }.each { |f| puts f.upcase }

※ 最初の命令に括弧

()
を付けることで、ファイル名と区別するためです。

Ruby イテレーターブロック

.each
.map
.select
など、Ruby のイテレーターを出力処理に使用できます。

  • ls.each { |f| puts f.upcase }
  • cat(file.txt).map { |line| line.strip }

インライン Ruby 評価

大文字で始まる行は、直接 Ruby コードとして評価されます。

rubish$ Time.now
=> 2025-01-01 12:00:00 +0900

rubish$ Dir.glob('*.rb').sort
=> ["Gemfile", "Rakefile"]

Ruby アレイと正規表現

Ruby アレイリテラルや globs パターンがシェルコンテキストで直接使えます。

  • rubish$ [1, 2, 3].map { |x| x * x }
    =>
    [1, 4, 9]

Lambda と関数定義

Lambda 表現

-> { }
や Ruby スタイルの
def...end
をサポートします。

rubish$ -> { 2 ** 10 }
=> 1024

def greet(name)
  echo "Hello, $name"
end

greet world
# => Hello, world

カスタム Ruby プロンプト

rubish_prompt
および
rubish_right_prompt
を Ruby 関数として定義し、動的コンテンツや Git 情報を表示できます。

def rubish_prompt
  branch = `git branch --show-current 2>/dev/null`.strip
  dir = Dir.pwd.sub(ENV['HOME'], '~')
  "\e[36m#{dir}\e[0m \e[33m#{branch}\e[0m $ "
end

def rubish_right_prompt
  Time.now.strftime('%H:%M:%S')
end

遅延読み込み (
lazy_load
)

環境変数の初期化や

rbenv init
などの重い処理を、次のプロンプト直前まで背景スレッドで延期できます。

# ~/.rubishrc 内
lazy_load { `rbenv init - --no-rehash bash` }
lazy_load { `nodenv init - bash` }

制限モード (
-r
)

不信任なスクリプト実行時に、Ruby 統合機能(インライン評価、ラムダなど)を全無効化します。標準的なシェル構文のみが利用可能です:

rubish -r script.sh

Zsh 互換性

  • setopt
    /
    unsetopt
  • compdef
    /
    compinit
    autoload
    (fpath)
  • %X
    プロンプトコード
  • 簡略化されたパス展開 (
    a/c<Tab>
    )

設定ファイル

順に読み込まれる構成ファイルです。

  • ログインシェル:
    1. /etc/profile
    2. ~/.config/rubish/profile
      または
      ~/.rubish_profile
  • インタラクティブシェル:
    1. ~/.config/rubish/config
      または
      ~/.rubishrc
    2. ./.rubishrc
      (プロジェクトローカル)
  • ログアウト:
    1. ~/.config/rubish/logout
      または
      ~/.rubish_logout

Ruby プログラムへの埋め込み

公開 API を提供し、ターミナルエミュレーターや GUI から Rubish セッションを直接制御できます(Echoes ターミナルなどで利用中)。

require 'rubish'

repl = Rubish::REPL.new(login_shell: true)

# インタラクティブ実行
repl.run

# プログラマティックな操作
repl.tokenize('ls | grep foo')
repl.try_parse('if true; then')
repl.parse_ast('echo hi')
repl.complete_at(line: 'gi', point: 2)

Subprocess Hook

fork()
/
exec()
の間に子プロセスで実行されるフックを設定できます。

Rubish::Command.child_pre_exec_hook = -> {
  Process.setsid
  # ...ioctls, シグナルハンドラなど...
}

ビルトインコマンド一覧

カテゴリコマンド
ディレクトリcd, pwd, pushd, popd, dirs
I/Oecho, printf, read, mapfile, readarray
変数export, declare, typeset, readonly, unset, local, shift, set
プロセスexit, logout, exec, kill, wait, times
ジョブ制御jobs, fg, bg, disown, suspend
関数function, return, caller
Aliasalias, unalias
履歴history, fc
実行eval, source, ., command, builtin
テストtest, [, [[, (( )), let
制御break, continue, trap
補完complete, compgen, compopt, bind
設定shopt, setopt, unsetopt
情報help, type, which, hash
その他true, false, :, getopts, umask, ulimit, enable

開発

bundle install
bundle exec rake test

コントリビューション

バグ報告とプルリクエストは GitHub をご検討ください。 https://github.com/amatsuda/rubish

ライセンス

MIT

同じ日のほかのニュース

一覧に戻る →

2026/05/24 3:45

私の Writerdeck を語る時が来ました。

## 日本語翻訳: 著者は、6年経った System76 Galago Pro ラップトップを「writerdeck」と名づけたオフライン書写ステーションに変換し、X11、Wayland、およびデスクトップ環境を排する tty ベースの構成で Debian Trixie を実行することでミニマリズムを優先しています。コンテンツが公開共有を目的としているためフルディスク暗号化は省略され、管理には `sudo` ユーザーモデルに切り替えて root ログインが無効化されました。本質的なツールとして、Neovim がテキスト編集に使用され(従来のエディタに代わり)、Debian バックポートからの `kmscon` でスケーラブルなターミナルウィンドウを可能にし、セッション多重化には `tmux` を使用し、インストール済みの Network Manager 経由の `nm-tui` が Wi-Fi/WAN の管理に用いられます。電力モニタリングおよび画面明るさ制御は `acpi` と `light` コマンドで行われ、自動ログインと `.bashrc`内の起動スクリプトにより Neovim が `tmux` セッション内で動作し、ブート時に Vimwiki が起動するようにしています。Syncthing は Vimwiki フォルダをリモートサーバーに同期させ、ブラウザ GUI を必要とせずオフラインファーストなワークスペースを維持するために全てのネットワークアドレスを活用しています。この構成はデジタルの雑多さを削減し、悪い書写習慣を打破助けるとともに、クリエイティブ専門家にとってセキュリティと生産性を向上させます。

2026/05/24 7:25

自分でロールを作るな

## 日本語訳: 要約: 開発者は、暗号化やユーザーインターフェースコンポーネントといった重要な機能に対して独自の実装を即時に停止する必要があります。なぜなら、「自分自身でつくる」というソリューションは過去の実績が証明する通り危険であるためです。最も重要な教訓は、安全性と使い勝手を確保するために、自作コードの代わりに既成でピアレビューされた標準を採用しなければならないことです。独自のカスタム暗号化パッケージには、初期化の不備や予測可能なパターンなどの深刻な欠陥を内包しており、規制産業では財務規制に違反し、高額の罰則を引き起こす可能性があります。セキュリティの問題だけでなく、ネイティブブラウザ要素を置換することは性能低下をもたらし、過剰な JavaScript ロジックによりキーボードスクロールの破損やリンクの読み込み遅延といった問題を引き起こします。さらに、独自のソリューションは自動入力機能など、安全なパスワード管理などの重要なネイティブ機能を排除してしまいます。この傾向は、組み込みブラウザ機能の安定性よりも創造的なツールの構築を優先しており、ユーザー(高齢者のご家族も含まれます)が慣れ親しんだツールを常に再学習することを強いられています。これらの使い勝手に関する落とし穴を防ぎ、規制当局による罰金を避けるためには、開発者はネイティブ要素を置換するのではなく補完する方向へ転換すべきです。これにより、すべてのウェブサイトで一貫した動作を確保できます。

2026/05/21 6:21

私の二画面デスクセットアップ(2025)

## 日本語訳: 著者は、壁を向いた単調なパソコンデスクを部屋の方を向くように回転させることで(ドアを見渡させ、奥行きを追加)、そしてテック専用だった単一の面を、二つの明確なゾーニングに分かれた大規模な USM ハラーデスクに置き換えることにより、ハイブリッドなワークスペースへと成功裡に変化させています。このデザインは、ソーシャルメディアでのフィードバックを受けてから以前の壁を向いた配置が持っていた「古い」外観に対応し、また、未使用のアイテム、おもちゃ、プロジェクトをアナログ側の面に置き続けることで、ストイックなミニマリズムの限界を解決し、アイデアを刺激することを可能にしています。単純にチェアを二つの半分の間で移動させることで強化された明確な精神的境界線により、このセットアップは一つの表面上で「作業」「思考」「子供たちと過ごす時間」という 3 つの異なる機能を発揮します。9 ヶ月の使用後、著者は単一コンピューターの配置に戻る予定はないことを確認しており、むしろミニマリスト的な規律とマキシマリスト的な柔軟性を融合させたこの柔軟なシステムを維持する意欲を持っています。これにより、別々の部屋を必要とせずに、ワークフローと創造的アウトプットを向上させることができます。

Rubish:純粋な Ruby で書かれた Unix シェル | そっか~ニュース