Brush (Bo(u)rn(e) RUsty SHell) a POSIX and Bash-Compatible Shell in Rust

70 voxadam 30 5/6/2025, 6:47:49 PM github.com ↗

Comments (30)

d4mi3n · 2h ago
Since everyone is sharing shells written in Rust, I've become quite fond of Nushell: https://www.nushell.sh/

I'd love to see more shell exploring things beyond POSIX. Text based stdin/stdout will always have its place, but having ways to express, serialize, and pass along data in more structured ways is quite nice.

BrouteMinou · 41m ago
You should try powershell
nulld3v · 32m ago
+1 on nushell, it is incredible. Having all data typed and structured is an insane superpower.

Common worries I hear from people that were non-issues in practice:

- Not POSIX compatible: Nushell doesn't aim to replace POSIX, there's no problem with dropping back to bash to execute some shell snippets

- You need to re-learn everything: I'm not a huge fan of how the commands are organized, but I still didn't find it that difficult. nushell's prompt/readline comes with an inline help menu with fuzzy search. Hit CTRL+O to edit a command/pipeline in your IDE/editor of choice with LSP backed intellisense, type-checking and in-editor command docs/help. The syntax is very simple and intuitive.

- Just use python: Sure, but python comes with a lot of disadvantages. It's slow and uses dynamic typing. Static typing in nushell catch typos in pipelines & scripts before they execute. It also makes in-shell and IDE LSP tab-completions very accurate. Large files process quickly though it will still consume more memory if you aren't able to process all the data in a streaming fasion. It's like having jq but with autocomplete and it works on all command output & shell variables. Though if you really like python, check out Oil/OSH/YSH: https://oils.pub/

- All Unix commands output text, structured data is useless in a shell: `detect columns` (https://www.nushell.sh/commands/docs/detect_columns.html) - now it's structured. Or use `from <format>` if the command outputs CSV, JSON, INI, YAML, etc... Or don't, cause GNU tools work fine in nushell if you keep everything in text format

And there are other crazy features too.

- Write nushell plugins in your language of choice, plugins can work with structured data

- Plugins can run in the background and maintain state, nushell can automatically start a plugin when it is first used and stop the plugin when it is idle

  - e.g. a plugin can open a SQL connection and use it across multiple commands.

  - There's a built-in plugin for opening in-mem/on-disk SQLite databases
- Data can carry metadata, e.g. binary data can carry its mime type, strings often carry metadata about which line and file the string was read from.

- Closures, generators, ranges, errors/exceptions + try-catch

- Support for IDE debugging via DAP is in progress

- Create your own hooks to customize how different types of data are displayed. Display structured data in table/tree form, display binary data in hex, etc...

- Collect related commands/variables into modules. Load a module knowing that you can easily unload the whole module later, module contents don't pollute global state. Variable declarations, env vars and loaded modules are scoped to the current code block, lowering the odds of a name collision.

The biggest downside of nushell is that it hasn't hit 1.0 yet so commands occasionally get renamed. Expect that you may occasionally need to tweak a script to get it working again. Definitely a pain point.

chubot · 1h ago
Hm I wasn't aware of this project, it seems to have started in 2022

Other than OSH, it seems to be the only shell that aims for POSIX/bash compatibility, out of dozens of alternative shells: https://github.com/oils-for-unix/oils/wiki/Alternative-Shell...

As far as I know, OSH is the most POSIX- and bash-compatible shell:

Nine Reasons to Use OSH - https://oils.pub/osh.html

If I have time, I will run this through our spec tests: https://oils.pub/release/0.29.0/test/spec.wwz/osh-py/index.h...

---

About this part: There are a number of other POSIX-ish shells implemented in a non-C/C++ implementation language

OSH is implemented in an unusual style -- we wrote an "executable spec" in typed Python, and then the spec is translated to C++.

That speeds it up anywhere from 2x-50x, so it's faster than bash on many workloads

e.g. a "fibonacci" is faster than bash, as a test of the interpreter. And it makes 5% fewer syscalls than bash or dash on Python's configure (although somehow this doesn't translate into wall time, which I want to figure out)

It's also memory safe, e.g. if there is no free() in your code, then there is no double-free, etc.

---

As mentioned on the OSH landing page, YSH is also part of the Oils project, and you can upgrade with

    shopt --set ysh:upgrade
If you want JSON and so forth, e.g.

    ysh$ json read < x.json
    ysh$ = _reply
    (Dict)   {shell: "ysh", fun: true}
YSH aims to be the "ultimate glue language" - https://oils.pub/ysh.html
koolba · 11m ago
> It's also memory safe, e.g. if there is no free() in your code, then there is no double-free, etc.

How does that work in practice? Is it an arena allocator per command execution? Fixed size preallocation of space for shell variable names and values?

Ericson2314 · 3h ago
This is interesting to me given https://github.com/NixOS/nix/issues/10823

We have a decent amount of code in bash that I'd like to get working on Windows too, once Nix on Windows is ready. I'm happy to rewrite it to a better language, but if I can get a non-CygWin/MSYS2 bash-compatible shell, that's a very nice thing to try out.

chasil · 2h ago
The easiest way to get POSIX and bashish scripts working on Windows is the busybox port:

https://frippery.org/busybox/index.html

This is actually the Almquist shell with many bashisms brought in (no arrays though).

  C:\>\bin\busybox sh
  C:/ $ uname -a
  Windows_NT MyHostname 10.0 22631 x86_64 MS/Windows
Edit: The ADA port below might interest you.

https://github.com/AdaCore/gsh

https://archive.fosdem.org/2019/schedule/event/ada_shell/

Ericson2314 · 2h ago
We do use bash's arrays and maps, though.
nikokrock · 8m ago
at the time it was mainly implemented to speed up compiler builds. Not using a cygwin based shell allowed a 3-5 speedup which was significant for our nightly builds
nikokrock · 11m ago
if you have interest i could have a look at adding support for these structures in gsh
Ericson2314 · 9m ago
That's good to know! I would say our Windows support is not yet at the point where I would feel comfortable making a feature request to your project, but let's keep in touch. :)
interroboink · 42m ago
The old "it's easier to port a shell than a shell script" quote comes to mind (:
harrison_clarke · 2h ago
there's the cosmopolitan libc one: https://cosmo.zip/pub/cosmos/bin/bash

you'd probably want the rest of the programs, too. bash isn't too useful on its own. you can also find those on the same website

Pet_Ant · 2h ago
Another *-nix shell written in Rust[1] (but neither POSIX nor Bash compatible[2]): Fish

[1] https://github.com/fish-shell/fish-shell/releases/tag/4.0.0

[2] https://fishshell.com/docs/current/design.html

parasense · 2h ago
This might seems like a rant for some of you, of even heretical to certain shell zealots... But it's about time we move past Posix compliance for shells. Don't get me wrong, it was a fabulous thing back in the 1980s and 1990s with respect to the Unix wars. But in a twist of irony Linux won the Unix wars, and these days Posix compliance, with respect to shells, mostly holds back innovation or modernization by pegging the concept of a terminal to something from 1988. Namely the Korn Shell (which is reference POSIX SHELL implementation back then), or even worse the Bourne shell. Doing get me wrong, I'm glad we're not on something like the C shell, but I'm pretty sure nobody today actually adhears to pure Posix compliance for shells scripting. So let's all just agree to drop the pretence snobbery, and move forward in a brave new world beyond Posix.
yjftsjthsd-h · 1h ago
There are two ways to attempt to move beyond POSIX sh:

1. You can do a superset of POSIX, like BASH and I think Zsh. This gives you a graceful upgrade path while maintaining backward compatibility, at the expense of being somewhat "stuck" in places. Oil is another attempt at exploring how best to use this path.

2. You can throw out POSIX totally, like fish and PowerShell. This lets you really improve things, at the expense of breaking backwards compatibility. IMHO, breaking compatibility is painful enough that it's really really hard to justify.

It's also worth pointing out that you can separate the roles of "interactive shell" and "shell for scripts". It is, for example, perfectly reasonable to use fish for interactive sessions while keeping /bin/sh around and perhaps even preferring dash as its implementation, which gives you compatibility with software while making things friendlier to users. I mean, I say this as someone who writes a lot of sh scripts and between that and years of practice my fingers expect something roughly sh-like, but I hear a lot of good things from folks who just switched their interactive shell to ex. fish.

kstrauser · 50m ago
That's what I do: interactive Fish, scripted Bash/sh, although I let myself write Fish scripts for my own local, personal scripting that I don't care about sharing with the rest of the world.
chasil · 1h ago
Suprisingly, POSIX has recently adopted the find -print0 | xargs -0 idiom, so the gears do turn, but very slowly.

The latest standards for POSIX.2 utilities are here:

https://pubs.opengroup.org/onlinepubs/9799919799/utilities/

I do agree with you that UNIX userland would be miles ahead of where we are now if the POSIX.2 standard could be cajoled out of the '80s.

kstrauser · 52m ago
I'm with you. I've used Fish for a few years now and I find it so much more ergonomic for having foregone strict POSIX compliance. I still write cross-platform stuff in Bash when it's going to run on machines I don't personally control, but I'll write all my routine local interactive stuff (like adding helper functions, wrappers for other commands, etc.) in Fish because it's a breath of fresh air.

I strongly disagree with the notion of only learning one shell language "because what if I telnet into an ancient Sun box and Fish isn't available?" In exactly the same way, I don't exclusively write my programs in C in case some remote host might not have Python or Rust or Fish some day. I'll cross that bridge when I come to it, but in the mean time I want to use something that makes me happy and productive.

cflewis · 1h ago
Things can be both a rant and true at the same time. I'm glad Fish didn't attempt Posix compliance.
Pet_Ant · 1h ago
Well the problem is that what should be the lingua-franca in a post POSIX/Bash world?

My preference is PowerShell. It's now open source [1], it has a wide install base, and is cross-platform. It is a bit heavy and slower to start (actually takes seconds), but the cleaness of it's record-based nature versus just string parsing is infinitely refreshing.

[1] https://github.com/PowerShell/PowerShell

kstrauser · 44m ago
chasil · 1h ago
It is unlikely to be PowerShell.

On my old i386 server, this is my fastest shell:

  $ ll /bin/dash
  -rwxr-xr-x 1 root root 85368 Jan  5  2023 /bin/dash
The set of features in the POSIX.2 shell is designed to minimize resource usage.

This is simply a place that PowerShell cannot go.

chubot · 1h ago
I think everyone agrees with you, and they did back in say 2016 when I started https://oils.pub

They also agreed with you in the early 1990's. There are some quotes from Richard Stallman, David Korn (author of AT&T ksh), and Tom Duff (author of rc shell) here lamenting Bourne shell:

https://www.oilshell.org/blog/2019/01/18.html#slogans-to-exp...

A problem with using a Bourne shell compatible language is that field splitting and file name generation are done on every command word

nobody really knows what the Bourne shell’s grammar is

---

But there is a "collective action" problem. Shell was the 6th FASTEST growing language on Github in 2022: https://octoverse.github.com/2022/top-programming-languages

I imagine that, in 2025, there are MORE new people learning POSIX shell/bash, than say any other shell here: https://github.com/oils-for-unix/oils/wiki/Alternative-Shell...

Because they want to get work done for the cloud, or embedded systems, or whatever

Also, LLMs are pretty good at writing shell/bash!

---

Oils is designed to solve the legacy problem. OSH is the most bash-compatible shell in the world [1]:

https://oils.pub/osh.html

and then you also have an upgrade to YSH, a legacy-free shell, with real data structures: https://oils.pub/ysh.html

YSH solves many legacy problems, including the exact problems from the 1990's pointed out above :-)

So to the extent that you care about moving off of bash for scripting, you should probably prefer OSH and YSH to Brush

It looks like Brush aims for the OSH part (compatible), but there is no YSH part (dropping legacy)

(I may run Brush through our spec tests to see how compatible it is, but looking at number of tests / lines of code, I think it has quite some distance to go.)

[1] e.g. early this year, Koichi Murase rewrote bash arrays in OSH to use a new sparse data structure, which I mentioned in the latest blog post. Koichi is the author of the biggest shell program in the world (ble.sh), and also a bash contributor.

https://github.com/oils-for-unix/oils/wiki/The-Biggest-Shell...

Zambyte · 2h ago
I didn't realize fish was written in Rust, and it was my primary shell for a few years. Looks like they couldn't resist the rewrite it in Rust meme :-D

https://github.com/fish-shell/fish-shell/tree/c2eaef7273c555...

vs the C++

https://github.com/fish-shell/fish-shell/tree/d9d3557fcfbce1...

nicce · 2h ago
They have pretty good writings about the journey. Sounds like they eliminated ”accidentally” quite many bugs in the process.

Initial motivation: https://github.com/fish-shell/fish-shell/pull/9512#issuecomm...

kstrauser · 40m ago
That's a very new change. The first Rust beta version just came out in December 2024: https://fishshell.com/blog/fish-4b/

I switched to the beta on the day it was released and haven't had one single issue with it. That was the smoothest rewrite I've ever seen.

Zambyte · 39m ago
Glad it went well! I'd still be using it if it weren't for the fact that Guix didn't play very nicely with it when I switched to that. Might give it another shot at some point though, it was very nice.
ris · 47m ago
This is cool, but still

(...HN formatting fail, imagine shell output showing the nixpkgs bash binary is 1.1M, the brush binary is 6.9M...)

with no prospect of further amortizing that size through shared libraries. Without shared libraries the only chance I see for rust being used to replace base system tools is with multi-call binaries a la busybox.

Muromec · 2h ago
That's nice. Somehow it doesn't play nice with fzf scripts (/usr/share/fzf/key-bindings.bash and /usr/share/fzf/completion.bash)