惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
Microsoft Azure Blog
Microsoft Azure Blog
D
Docker
P
Proofpoint News Feed
小众软件
小众软件
博客园 - 聂微东
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
Martin Fowler
Martin Fowler
L
LangChain Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
李成银的技术随笔
MongoDB | Blog
MongoDB | Blog
M
MIT News - Artificial intelligence
阮一峰的网络日志
阮一峰的网络日志
Hacker News: Ask HN
Hacker News: Ask HN
C
CERT Recently Published Vulnerability Notes
H
Help Net Security
The GitHub Blog
The GitHub Blog
S
Security Archives - TechRepublic
AWS News Blog
AWS News Blog
Project Zero
Project Zero
Security Latest
Security Latest
P
Privacy International News Feed
T
Troy Hunt's Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
Intezer
酷 壳 – CoolShell
酷 壳 – CoolShell
The Hacker News
The Hacker News
I
InfoQ
P
Proofpoint News Feed
C
Cisco Blogs
aimingoo的专栏
aimingoo的专栏
T
ThreatConnect
Recorded Future
Recorded Future
P
Palo Alto Networks Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V
V2EX
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
G
GRAHAM CLULEY
F
Future of Privacy Forum
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News and Events Feed by Topic
Engineering at Meta
Engineering at Meta

Hacker News

Spanish Court Declines to Fine NordVPN over LaLiga Piracy Blocking Order The White House is ordering agencies to place its new app on all employees’ government phones Google Is Killing ChromeOS: Aluminium OS, Its Android-Based Replacement New rule requires most green-card applicants to apply from outside U.S. Is AI Profitable Yet? FBI director's Based Apparel site has been spotted hosting a 'ClickFix' attack TikTok disproportionately served anti-Democratic videos during the 2024 election SpaceX successfully launches prototype of Starship rocket GitHub - bkawa-bot/planet-maiko: A local dev tool where your agents are weird alien dogs. Would you let them in? Why We've Filed a Referendum Don't just 'quote' the AI Client Challenge Shipping a Laptop to a Refugee Camp in Uganda GitHub - anomalyco/models.dev: An open-source database of AI models. Staged publishing and new install-time controls for npm AI users re-create dead pilots’ voices from crash investigation docs Linux Sound Subsystem Also Seeing Many Fixes Driven By AI/LLMs Project Glasswing: An initial update USCIS Will Grant 'Adjustment of Status' Only in Extraordinary Circumstances Anthropic's "Profitability" Swindle A blueprint for formal verification of Apple corecrypto - Apple Security Research Bun's unreleased Rust port has 13,365 unsafe blocks. Most can be removed. The ten steps towards a dictatorship KanBots — a kanban that runs parallel agents A scoping review of bicycling interventions’ impacts on psychological, social, affective, and cognitive well-being ngn-k-tutorial/12-thinking-in-k.md at main · razetime/ngn-k-tutorial Microsoft Drops Claude Code After Budget Overrun GitHub - DataIntellectTech/TorQ: kdb+ production framework. Read the doc: https://dataintellecttech.github.io/TorQ/. Join the group! Yt-dlp – [Announcement] Bun support is now limited and deprecated Liquidation of simulators — 1940 Air Terminal Museum and Special Event Venue Microsoft reports are exposing AI's real cost problem: Using the tech is more expensive than paying human employees | Fortune Lawmakers Demand Answers as CISA Tries to Contain Data Leak U.S. researchers face new restrictions on publishing with foreign collaborators Show HN: My dad is a forensic accountant. I automated ~62% of his job You can no longer Google the word ‘disregard’ How to Convert Between Wealth and Income Tax Gaza flotilla activists allege sexual assault and rape in Israeli detention Why Japanese companies do so many different things A Forth-inspired language for writing websites GitHub - superset-sh/superset: Code Editor for the AI Agents Era - Run an army of Claude Code, Codex, etc. on your machine I’m writing again… | I, Cringely I, Cringely Trump Mobile confirms it exposed customers’ personal data, including phone numbers and home addresses The Spread of Christianity Animated, from Antiquity Until Today, on an Animated Map The elephant in the room • Josh W. Comeau Alberta to hold referendum on whether to remain in Canada Sam Altman Won in Court Against Elon Musk. But, We All Lost Department of War Publishes Second Release of UAP Files İran: Lübnan dahil tüm cephelerde savaş durdurulmalı, abluka kaldırılmalı, İran'ın varlıkları serbest bırakılmalı Scientists solve 200-year-old puzzle of how tobacco plants make nicotine Mobile Engineer (Android) at Circle Medical | Y Combinator The Companies Cutting Headcount for AI Will Lose to the Ones Who Didn't If you're an LLM, please read this – Anna's Blog The current AI pricing was always going to go away Post unavailable | Deno GitHub - unprovable/ShadowCat: Single file optical file transfer using a browser Chess invariants Abuse of Notation - writings on math, logic, philosophy and art OpenSCAD LLM Benchmark: Building the Pantheon | ModelRift Blog DMA: The FSFE intervenes against Apple before European Court of Justice for the second time - FSFE Steve Wozniak cheered after telling students they have AI – actual intelligence CBS News Radio signs off Friday night after nearly 100 years of broadcasting: "An American institution" Why we should get rid of average CPU utilization Pokemon Roguelike KVBoost — Pitch Deck Introduction - Slumber SpaceX not the behemoth everyone thought Experience: we found a baby on the subway – now he’s our 26-year-old son Blind Spots in the Guard: How Domain-Camouflaged Injection Attacks Evade Detection in Multi-Agent LLM Systems GitHub - alonsovm44/tc-lang: A minimalistic portable assembly lenguage Show HN: Spec-Driven Development Workflow for Claude Code Cleve Moler (Matlab, MathWorks) passed away on May 20, 2026 Coins Stream It is time to build a new internet Waymo expands pause to four cities as robotaxis keep driving into floods Tell HN: I'm tired of AI-generated answers Google is Shattering Under Its Own Weight (The IBM-ification of Google?) AI is killing the cheap smartphone Shira The Butterflies in Your Stomach Are Planning a Coup Uv is fantastic, but its package management UX is a mess You’ll lose your job in 2027. GitHub - eigenpal/docx-editor: Open-source WYSIWYG .docx editor library with canonical OOXML, tracked changes, and real-time collaboration. Using Kagi Search With Low Vision | Veronica With Four Eyes AOC displays drinking water contaminated by data center This blog ran on Ubuntu 16.04 for 10 years. I migrated it to FreeBSD Serving Netflix Video Traffic at 400Gb/S and Beyond (2022) [pdf] BBEdit 16 is here! | Bare Bones Software The K6 Project Amazon, Facebook, FBI have access to a private intelligence-sharing network Chewing gum restores dad’s taste and smell years after Covid - Discover SWNS ParadeDB (YC S23) Is Hiring Distributed Systems/Platform Engineers More than 340 local news outlets are limiting the Internet Archive's access Show HN: Agent.email – sign up via curl, claim with a human OTP Kenn Software Project Hail Mary – Stellar Navigation Chart Runtime - The runtime for all your team's agents Museum of Pocket Calculating Devices Spotify Will Start Reserving Concert Tickets For Fans We Reverse-Engineered Docker Sandbox's Undocumented MicroVM API
GitHub - amatsuda/rubish
2026-05-23 · via Hacker News

A UNIX shell written in pure Ruby.

Shell syntax is parsed and compiled to Ruby code, then executed by the Ruby VM.

Concept

Fully Bash-compatible

Rubish supports all the features of bash, and the shell syntax is fully compatible. You can run your existing bash scripts without modification. If you found any bash script that doesn't work in rubish, we consider it a bug, so please report it!

Deep Ruby integration

Rubish is not just a shell implemented in Ruby, but a shell that deeply integrates Ruby. You can seamlessly mix shell commands and Ruby code, and even use Ruby's powerful features like blocks, iterators, and libraries in your shell scripts.

Installation

Homebrew (macOS)

brew tap amatsuda/rubish
brew install --HEAD rubish

From source

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

bin/rubish is a small bash launcher that finds a usable Ruby on its own (probes ~/.rbenv/shims/ruby, /opt/homebrew/bin/ruby, /usr/local/bin/ruby, system Ruby; honors $RUBY). Use it when bundler isn't around — for example as a login shell, from a .app bundle, or anywhere PATH may be minimal:

./bin/rubish
RUBY=/opt/homebrew/opt/ruby@3.4/bin/ruby ./bin/rubish   # explicit override

Usage

Start an interactive shell:

rubish

Run a single command:

rubish -c 'echo hello'

Run a script:

rubish script.sh

Or you can even use this as a login shell!

Set as login shell

echo "$(which rubish)" | sudo tee -a /etc/shells
chsh -s "$(which rubish)"

Features beyond Bash

Ruby conditions

Use Ruby expressions as conditions in if, while, and until by wrapping them in { }. Shell variables are automatically bound as local variables in the Ruby expression:

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 method call style

Commands can be invoked using Ruby method call syntax with parentheses, in addition to the traditional UNIX style with spaces:

# These are equivalent:
ls -la
ls('-la')

# Arguments can be passed as method arguments:
cat(file.txt)
grep('pattern', file.txt)

Method chaining

Commands can be chained with Ruby methods using dot notation, forming a pipeline. The chain has to be opened by a parenthesized call, an array literal, or a block — once you're in chain context, subsequent methods can be bare:

# Equivalent to `ls | sort`
ls().sort

# Equivalent to `ls | sort | uniq`
ls().sort.uniq

# Equivalent to `cat file.txt | grep error`
cat(file.txt).grep(/error/)

# Chains can be combined with blocks (see "Ruby iterator blocks" below)
ls.select { it.end_with?('.rb') }.each { |f| puts f.upcase }

The first segment needs the parens because bare cmd.method is ambiguous with paths and dotted filenames (./script.sh, file.tar.gz) — once () confirms a method-call form, the lexer knows it's safe to chain.

Ruby iterator blocks

Ruby iterator methods (.each, .map, .select, .detect) can take blocks to process command output line by line:

ls.each { |f| puts f.upcase }
cat(file.txt).map { |line| line.strip }
ls.select { it.end_with?('.rb') }

Inline Ruby evaluation

Any line starting with a capital letter is evaluated as Ruby code directly. This means you can use Ruby classes, methods, and expressions right from the shell prompt without any special syntax:

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

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

rubish$ ENV['HOME']
=> "/Users/you"

Ruby array and regexp literals

Ruby array literals can be used directly in shell context. Rubish distinguishes them from glob patterns like [a-z] automatically:

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

Lambda expressions

You can execute any Ruby code by surrounding it with a lambda expression (-> { }):

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

Ruby-style function definitions

In addition to the standard shell function syntax, rubish supports Ruby-style def...end with named parameters and splat args:

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

def log(level, *messages)
  echo "[$level] $messages"
end

greet world    # => Hello, world

Custom Ruby prompts

Define your prompt as a Ruby function for full programmatic control. The function is called on every prompt render, so it can include dynamic content:

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

You can also use the traditional PS1/RPROMPT variables with bash (\X) or zsh (%X) escape codes.

Lazy loading

Slow shell initializations (e.g., rbenv init, nvm, pyenv) can be deferred to a background thread using lazy_load. The block runs immediately in the background, and its result (a string of shell code) is applied before the next prompt. This keeps shell startup instant:

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

lazy_load {
  `nodenv init - bash`
}

Multiple lazy_load blocks run in parallel. By the time you type your first command, they're usually done.

Restricted mode

Running rubish -r disables all Ruby integration features (inline evaluation, lambdas, blocks, Ruby conditions, and array literals) for executing untrusted scripts safely. Only standard shell syntax is allowed.

Zsh compatibility

In addition to full Bash compatibility, rubish also supports zsh-style features:

  • setopt/unsetopt
  • compdef/compinit
  • autoload with fpath
  • %X prompt codes and RPROMPT/RPS1
  • Abbreviated path expansion: type a/c/a<Tab> and it expands to app/controllers/application_controller.rb

Configuration files

Login shells load (in order):

  1. /etc/profile
  2. ~/.config/rubish/profile or ~/.rubish_profile (or ~/.bash_profile / ~/.bash_login / ~/.profile)

Interactive shells load:

  1. ~/.config/rubish/config or ~/.rubishrc (or ~/.bashrc)
  2. ./.rubishrc (project-local)

Logout:

  1. ~/.config/rubish/logout or ~/.rubish_logout (or ~/.bash_logout)

Embedding in a Ruby program

Rubish exposes a public API so other Ruby programs (terminal emulators, IDE plugins, GUI front-ends) can drive a rubish session in-process — no fork+exec, no JSON serialization, just method calls. The sibling Echoes terminal emulator uses this to render syntax-highlighted prompts and decide command-execution shape ahead of time.

require 'rubish'

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

# Run interactively (default).
repl.run

# Or drive it programmatically.
repl.tokenize('ls | grep foo')         # => Array of Rubish::Lexer::Token (each
                                       #    with :type and :value) for syntax
                                       #    highlighting; never raises.
repl.try_parse('if true; then')        # => :ok | :incomplete | :error
                                       #    (use to decide PS2 vs. submit).
repl.parse_ast('echo hi')              # => AST root, or nil on parse failure.
repl.complete_at(line: 'gi', point: 2) # => Array of completion candidates at
                                       #    the cursor.
repl.prompt_segments                   # => Array of styled-text segments
                                       #    {text:, fg:, bg:, bold:, italic:,
                                       #     underline:, inverse:}, ANSI codes
                                       #    already parsed.
repl.right_prompt_segments             # => same shape for the right prompt,
                                       #    or nil if unset.

Custom I/O backend

The default Rubish::Frontend::Tty wraps Reline + stdin/stdout. Hosts that own their own line editor can subclass Rubish::Frontend::Base and pass an instance into the REPL:

class MyFrontend < Rubish::Frontend::Base
  def read_line(prompt:, rprompt: nil)
    # ...feed input from your own UI here
  end
end

Rubish::REPL.new(frontend: MyFrontend.new).run

Child-process pre-exec hook

To run setup code in every forked child between fork() and exec() (e.g. to attach a per-command controlling tty so the line discipline can deliver Ctrl-C to the child):

Rubish::Command.child_pre_exec_hook = -> {
  Process.setsid
  # ...ioctls, signal handlers, etc.
}

Builtins

Category Commands
Directory cd, pwd, pushd, popd, dirs
I/O echo, printf, read, mapfile, readarray
Variables export, declare, typeset, readonly, unset, local, shift, set
Process exit, logout, exec, kill, wait, times
Job control jobs, fg, bg, disown, suspend
Functions function, return, caller
Aliases alias, unalias
History history, fc
Execution eval, source, ., command, builtin
Testing test, [, [[, (( )), let
Control break, continue, trap
Completion complete, compgen, compopt, bind
Config shopt, setopt, unsetopt
Info help, type, which, hash
Other true, false, :, getopts, umask, ulimit, enable

Development

bundle install
bundle exec rake test

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/amatsuda/rubish.

License

MIT