6 ms·
Brush (Bo(u)rn(e) RUsty SHell) a POSIX and Bash-Compatible Shell in Rust
- Ericson2314 1y agoThis is interesting to me given https://github.com/NixOS/nix/issues/10823 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 1y agoThe easiest way to get POSIX and bashish scripts working on Windows is the busybox port: https://frippery.org/busybox/index.html 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://github.com/AdaCore/gsh https://archive.fosdem.org/2019/schedule/event/ada_shell/ https://archive.fosdem.org/2019/schedule/event/ada_shell/
- Ericson2314 1y agoWe do use bash's arrays and maps, though.
- nikokrock 1y agoif you have interest i could have a look at adding support for these structures in gsh
- Ericson2314 1y agoThat'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. :)
- chubot 1y agoI am not sure if this helps or not, but if you want a bash-compatible shell on Windows, translating Oils to Ada, or porting it to Windows could be easier than adding bash arrays https://news.ycombinator.com/item?id=43910883 https://news.ycombinator.com/item?id=43910883 (similar comment about Rust) Bash arrays are extremely hairy, with many corner cases, and differ from bash version to version. And in particular, the shell code in Nix DOES RELY on these corners (e.g. https://www.oilshell.org/blog/2024/06/release-0.22.0.html https://www.oilshell.org/blog/2024/06/release-0.22.0.html) --- I mentioned in another comment that Koichi Murase, who is a bash contributor, and wrote the largest shell program in the world, just overhauled the bash array support in OSH A few relevant test files -- Koichi added a huge number recently: https://oils.pub/release/0.29.0/test/spec.wwz/osh-py/array-sparse.html https://oils.pub/release/0.29.0/test/spec.wwz/osh-py/array-s... https://oils.pub/release/0.29.0/test/spec.wwz/osh-py/array-assoc.html https://oils.pub/release/0.29.0/test/spec.wwz/osh-py/array-a... https://oils.pub/release/0.29.0/test/spec.wwz/osh-py/ble-idioms.html https://oils.pub/release/0.29.0/test/spec.wwz/osh-py/ble-idi... Our tests are thorough enough that we ROUTINELY find bugs in bash, like integer overflow bugs. Koichi also knows about the differences between say bash 4.3, 4.4, 5.0, 5.1, etc. Because he wrote a very large program that uses bash arrays all over the place. --- Feel free to use our tests in any case (other shells like the Scheme shell used to bootstrap Guix have) And feel free to post a message to https://github.com/oils-for-unix/oils https://github.com/oils-for-unix/oils if you're interested or have questions
- Ericson2314 1y agoDoes YSH work on Windows?
- chubot 1y agoIt doesn't, but in the last ~3 months I've come around to the idea that it should And I did a bunch of research on it (e.g. https://lobste.rs/s/qjzd9y/everyone_quotes_command_line_arguments https://lobste.rs/s/qjzd9y/everyone_quotes_command_line_argu... ) I did notice that git for windows uses a bash built with MSYS. And I noticed that Python's subprocess module implements pipelines with native Win32, not with MSYS. So that is something we can do in Oils, in theory I won't say it's high priority, but of course it's an open source project, and users often change the priorities Two things that would really help are (1) finding a skilled Win32 programmer and (2) getting another grant (we've gotten 3 in the past)
- nikokrock 1y agoat 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
- chasil 1y agoJust out of curiosity, how much faster is gsh than busybox? I believe that busybox is produced by the Windows cross-compiler that I have loaded from EPEL. Can gsh be built the same way?
- nikokrock 1y agoI never did the test. At the time we started the project busybox was not sufficient to use in a full build of gcc, binutils, gdb, ... Though I never tried using a cross compiler to compiler GSH should not be an issue
- chasil 1y agoThis is the MinGW cross-compiler for Windows that I found in EPEL. Alas, no ADA. "Using this toolchain allows you to build binaries for the following programming languages: C, C++, Objective-C, Objective-C++ and Fortran." https://fedoraproject.org/wiki/MinGW/Tutorial https://fedoraproject.org/wiki/MinGW/Tutorial I think all of these packages were pulled in the "yum install": $ rpm -qa | grep ming | sort mingw64-binutils-2.41-3.el9.x86_64 mingw64-cpp-13.2.1-7.el9.x86_64 mingw64-crt-11.0.1-3.el9.noarch mingw64-filesystem-148-3.el9.noarch mingw64-gcc-13.2.1-7.el9.x86_64 mingw64-headers-11.0.1-3.el9.noarch mingw64-libgcc-13.2.1-7.el9.x86_64 mingw64-winpthreads-11.0.1-3.el9.noarch mingw64-winpthreads-static-11.0.1-3.el9.noarch mingw-binutils-generic-2.41-3.el9.x86_64 mingw-filesystem-base-148-3.el9.noarch
- harrison_clarke 1y agothere's the cosmopolitan libc one: https://cosmo.zip/pub/cosmos/bin/bash 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
- interroboink 1y agoThe old "it's easier to port a shell than a shell script" quote comes to mind (:
- Pet_Ant 1y agoAnother *-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 https://github.com/fish-shell/fish-shell/releases/tag/4.0.0 [2] https://fishshell.com/docs/current/design.html https://fishshell.com/docs/current/design.html
- Zambyte 1y agoI 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/c2eaef7273c5558678bc0465bdf5bdaef90859cd/src https://github.com/fish-shell/fish-shell/tree/c2eaef7273c555... vs the C++ https://github.com/fish-shell/fish-shell/tree/d9d3557fcfbce1fe603623f536242c20e40b599b/src https://github.com/fish-shell/fish-shell/tree/d9d3557fcfbce1...
- nicce 1y agoThey 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#issuecomment-1410820102 https://github.com/fish-shell/fish-shell/pull/9512#issuecomm...
- kstrauser 1y agoThat's a very new change. The first Rust beta version just came out in December 2024: https://fishshell.com/blog/fish-4b/ 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 1y agoGlad 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.
- 1y ago
- Muromec 1y agoThat's nice. Somehow it doesn't play nice with fzf scripts (/usr/share/fzf/key-bindings.bash and /usr/share/fzf/completion.bash)
- d4mi3n 1y agoSince everyone is sharing shells written in Rust, I've become quite fond of Nushell: https://www.nushell.sh/ 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 1y agoYou should try powershell
- d4mi3n 1y agoI have! Nutshell to me feels like a reimagined powershell without the focus on windows admin.
- dgfitz 1y agoPowershell doesn’t “focus on windows admin” any more than bash focuses on linux admin. What do you mean?
- d4mi3n 1y agoIt’s available in other OSs now, but my exposure to it has mainly been windows server and endpoint environments. YMMV, I’m mainly speaking from my own experience/history with powershell. For a long time it was the only way I knew of to manage various aspects of low level windows OS settings.
- dgfitz 1y agoGotcha. Speaking as someone who isn’t a fan of windows after about windows 2000, powershell is quite powerful, if not a touch verbose. Worth reading up on if you have a need to use it on any kind of cadence.
- GuB-42 1y ago
- chubot 1y agoHm 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-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 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.html 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 https://oils.pub/ysh.html
- koolba 1y 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?
- chubot 1y agoGood question -- at first I thought we would use an arena, at least for the parser. But we ended up writing a garbage collector for the subset of C++ we generate! That was completed in 2023: Pictures of a Working Garbage Collector https://www.oilshell.org/blog/2023/01/garbage-collector.html https://www.oilshell.org/blog/2023/01/garbage-collector.html https://news.ycombinator.com/item?id=34350260 https://news.ycombinator.com/item?id=34350260 There are two reasons to have a GC: (1) The AST (aka "lossless syntax tree") is actually GRAPH - it is useful to share nodes. I think graphs are fairly common for ASTs. Once a node can have multiple parents, then ownership becomes less clear, and errors using arenas can easily cause memory safety bugs. For example, in Rust, I think you start using Rc<T> and so forth, which is automatic memory management at runtime. (2) YSH is part of Oils, and it has nested dicts and lists like Python and JavaScript. Once you have nested dicts and lists, you need GC. We actually have the GC at the "meta-level", and that (somewhat surprisingly) saves a ton of code and bugs. It's like writing a Python/Ruby interpreter in Java or Go, and re-using the platform GC, rather than writing one specific to your language. In particular, we don't have GC rooting, ownership, or anything like Py_INCREF/DECREF littered all over the codebase. This makes our implementation like an executable spec! And that makes it very easy to contribute -- you write typed Python, and it's as fast as shells written in C. I think it's the best of both worlds --- Something I've pointed out over the years, and which many people find illuminating, is - bash doesn't have nested maps and arrays -- it only has flat ones. Therefore it doesn't need GC - awk too - it doesn't need GC, because its data structures are limited - https://news.ycombinator.com/item?id=28785732 https://news.ycombinator.com/item?id=28785732 - make and cmake too. I put all these "weak glue" languages in the "string-ish" category. In contrast, YSH gains A LOT of power from having real data structures, and that requires GC. (Writing a GC was the hardest part of the project -- I think sh/awk/make/cmake left it out for a reason! Even nushell has no GC I believe. fish lacks a GC too.) YSH has more of the power of Python/JS/Ruby, which if you look at it historically, did "replace" shell and awk for a huge set of problems. (Guido van Rossum specifically mentioned the "hole" between shell and C as a motivation for Python.) Garbage Collection Makes YSH Different - https://www.oilshell.org/blog/2024/09/gc.html https://www.oilshell.org/blog/2024/09/gc.html --- On a different note, if anyone really wants a shell buildable with the Rust toolchain, it would be worthwhile to TRANSLATE Oils to Rust. This will definitely work, because Oils is translated to C++ (completed in early 2024). You would have to write the runtime, which is around 4K lines for the garbage collector, and 4K lines for the OS bindings. That's a lot easier than writing a bash-compatible shell. That is, Oils has about 8K lines of hand-written C++ code. Compare with bash which is 162K+ lines of C written from scratch -- it's 20x less. I think 8K lines of unsafe code is also comparable to Rust binaries. e.g. prior to ~2018, Rust binaries used dlmalloc by default, which is 20-30K lines of C code. (What's important is that almost all PRs modify safe code only -- it is very easy to review typed Python) This would be a fun exercise for anybody interested in writing a GC in Rust (which is a hard challenge, with many nontrivial choices). You can write a GC, and get a shell for free, etc. --- Also, Brush and nushell are different projects ... Oils has both things -- OSH and YSH -- compatible and new So you actually get 2 shells for free by doing that :-P The "executable spec" strategy took a long time, but it actually worked!
- deleted 1y ago[deleted]
- ris 1y agoThis 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.
- parasense 1y agoYou're right about the Rust static binary size. Hello world is really large, and it's unamusing how so much of the standard library is creamed into the resulting binary, no matter how trivial... Do you know the current status of dynamic linking? I guess the lack of ABI stability is the big blocker, right? Probably no use in formalizing the linking bits if the goal posts keep moving. So it seems like the big problem is some committee will never complete the task... Because it will never be perfect... Something like that.
- lilyball 1y agoGankra wrote a good piece about all the work involved in this years ago (specifically, what Swift had to go through to get ABI stability) <https://faultlore.com/blah/swift-abi/ https://faultlore.com/blah/swift-abi/>
- sally_glance 1y agoThank you for this reference, it's a great read and actually gave me a better understanding of ABI compatibility issues in general. Probably the wrong place to ask, but where is the claim that static compilation is "hurting battery life" coming from? More efficient use of CPU caches because frequently used shared libs are more likely to be cached? Or less allocations in RAM maybe?
- ris 1y agoI think it's about more than just having ABI stability - the rust ecosystem is built around applications being able to demand exact micro-versions of every dependency and that falls apart when you want multiple non-cooperative applications sharing the same crate binary.
- koakuma-chan 1y ago> Its Linux build is fully supported running on Windows via WSL So I would run WSL in powershell, and Brush in WSL?
- hdjrudni 1y agoOther than being written in Rust, what are it's selling points? I'm not seeing anything in the README. Is it faster, but otherwise identical to bash? And if yes, are there any sorts of benchmarks?
- cryptonector 1y agoLicense: MIT Implementation language: Rust That strikes me as enough for many use-cases.
- ohroy 1y agothat's cool but I can't find a reason to use it.
- deleted 1y ago[deleted]
- cryptonector 1y agoJoy!
- shiomiru 1y agoAnother POSIX shell in Rust I remember: https://github.com/nuta/nsh https://github.com/nuta/nsh But it no longer seems to be in active development.
- nbenitezl 1y agoMy favourite shell written in Rust is wezterm, totally recommend it. https://wezterm.org/ https://wezterm.org/
- kseistrup 1y agoWezTerm is a terminal emulator [that runs a shell], not a shell, isn't it?
- wiz21c 1y agoOnce again, a rust rewrite ends up with a weaker licence (bash is GPL, brush is MIT). I love rust, but please, keep free software free. If only because you most likely benefited from past free software.
- mystified5016 1y agoBRASH was right there