Ask HN: Are alternative (oil, nu, etc.) shells usable as daily drivers?

121 points by oblio ↗ HN
Hello folks,

People using alternative shells (oil shell, nu shell, etc) as daily drivers, how is your daily experience?

I'm talking about a professional work experience, i.e. you use the shell as your daily driver at your workplace, not just for playing around.

Fish is probably usable, but outside of fish, is there any other production-ready alternative shell?

145 comments

[ 4.3 ms ] story [ 191 ms ] thread
I personally use ZSH with Prezto, which makes it considerably better than vanilla ZSH. I've tried Nushell and it seems to work quite fine but it's really a different paradigm that makes you think of the data differently than *sh shells.
Yeah, I am really excited about Nu as a concept, but I think adoption needs to happen first, where enough people are saying “alright, screw bash script flavors”. I’d feel silly deploying it in a production workload.
How does it compare to oh my zsh?
Anecdote: I started with oh my zsh and moved over to prezto. One thing that immediately struck me with prezto is just how fast it was. The shell boot up was instant, I don't know what oh my zsh was doing but it would take a while before it became interactive.

I didn't care enough to dig deep into the why, but have happily been stuck on prezto for the last few years.

I transitioned from oh-my-zsh to prezto a few years back and really liked it. Equal or better in every way, sometimes much better (speed and customization in particular, prezto is fast and guides you to customize in maintainable ways)
I used ohmyzsh but it somehow got slow, so i switched to zpretzo. It didn't get slow. So that's my comparison :)
Yeah, I love some of the ideas of neo-shells but using zsh with oh-my-zsh (mostly because I've used it forever and have too much inertia to switch to prezto/starship) and I get most of those features without losing compatibility with the vast majority of shell scripts, guides or snippets I can find online.
I use eshell for most things, but I do have to occasionally pop open an ansi-term.
Bit of a strange one maybe but for my windows machine I've actually been using cmder (conEmu) with ZSH and over the past few years have been extending it with plugins to suit just right.

It's super fast supports everything I need now and couldn't work without it.

Correct me if I'm wrong, but cmder is a terminal emulator not a shell.

Beside this cmder is really great, but recently I switched to MS's own Terminal, which is maybe even better in my opinion. Especially the integrations with wsl2.

Right the shell is zsh integrated into it. I keep associating them together! Should have clarified!

I haven't played with ms' really but interesting the wsl2 integration.. will check it out.

I decided last year to bite the bullet and learn Powershell. I think I will no longer have to wonder if there is a better option anymore.
It’s pretty fantastic, the trouble is finding a tutorial which isn’t a blog post that was written in the early 2000s using outdated syntax.
What makes it good?
1. Piping object instead of string. This is what Powershell inspire other new generation shells.

2. .NET integration

3. Maintained by a large company. Extensively used in commercial.

To elaborate on "piping object instead of a string" Powershell just has lots of quality-of-life features. I think the fundamental problem these days with the shell "do one thing and do it well" concept is that nothing in traditional posix outputs structured data, so every single command and script is a mess of cobbled-together ad hoc parsers and sorters. In Powershell all the builtins emit structured data so there's no need to, for example, write a regex to parse out the mtime of a file. You just do `$file.LastWriteTime`.
I'm a Linux native guy and I haven't hardly touched Windows in years but I still find myself curious about PowerShell. Is PowerShell even remotely suitable as a Linux shell? Is there any hope for PowerShell on Linux, it's an interesting take on shells.
nushell has a similar philosophy to PowerShell but without the strange command names. PowerShell is probably tied too deeply to Windows and .NET to be suitable as a Linux shell
PowerShell has strange command names? Compared to what? grep, sed, awk, and a bunch of two letter abbreviations from the before-times?
Compared to what the majority of people who frequently use the terminal are used to.
It’s different so it’s bad. /s
I use Powershell as standard shell on WSL (Linux on Windows) Everything is the same as Windows
I switched my shell to pwsh a few years back when work had me doing heavy pwsh development. It worked, but…

1. It didn’t execute native commands directly, at least then, so I was cobbling together pwsh functions to imitate ls, etc.

2. The pipeline is awesome, but incompatible with the default UNIX/style, where commands produce and expect text.

Having said all of that, it worked and worked well, at least for my purposes (immersion and education).

The pwsh pipeline is far more powerful, esp. since it passes objects and can maintain those: command B can perform work on the results of command A and C can access the results of both A and B with relative ease. The same trick is possible in bash, e.g., but requires some funky redirect and pipe management.

One the pwsh work was done, I switched back to bash.

I have been using Powershell, primarily on Windows, as my primary shell for a few years. I honestly prefer it to bash. I don't set it as my default shell on Linux, but that's because 99% of my bash usage (and the majority of my Linux usage) these days is explicitly to test a piece of code written in bash.

Configured with PSReadline Emacs mode it really feels pretty much like bash for the most part, except better. https://github.com/lukeschlather/dotfiles/blob/master/src/Wi...

(Concrete better: copy-paste, selecting with the mouse, scrolling all just work. Copy-paste pastes multiline by default so you don't end up executing commands without a chance to review.)

I've been wanting to try out elvish which seems like it might be a cleaner and more "unixy" pwsh. https://elv.sh/

I would probably turn that around and ask why are you asking?

Outside of command line editing features, some kind of completion, novelties, and prettiness, I think most of the time it always comes back to "I chose this shell due to syntax, or programming of some kind". e.g. tcsh due to the C-ness of it.

I am writing this from Linux, been using csh on Solaris and then bash on linux since, well since back then... I have seen a lot of shells come out, but every time I switch to one I think about my personal needs in the shell and portability (I do manage a large number of boxes, and most of them do not have extra items installed, including shells) so I end up back at bash/dash/sh.

Again, I would ask myself what you need in the shell. If ZSH or Fish or csh or ksh or some esoteric shell fit the bill, why not just try it as a daily driver? I mean, what is the worst possible outcome? (unless you make a living making life support shell driven software...)

I use zsh, but even zsh is a bit long in the tooth.

I'm especially interested in daily interactive use.

I tried fish but it's a bit tricky in some contexts.

Powershell is a bit too alien in *NIX-land, even though I really like it's concepts.

nushell looks quite promising but it's still pre-1.0.

i know a fair few eshell users. i’m not among them but they’re out there
oh-my-zsh on Linux is absolutely great, especially with autosuggestions and syntax-highlighting enabled.

On Windows I've settled with Windows Terminal and clink.

I've tried Powershell too but never got used to it. The concept where everything is an object sounds great. But in practice, to me it only is when scripting. When doing interactive work on the command line (which is what I do all day), as a human, nothing beats plain text for me. Enlighten me if this I missed the point of Powershell.

> Enlighten me if this I missed the point of Powershell.

Plain-text has gotten annoying to me now (having to shell out to grep, cut, and awk is very meh).

What's your pain point when trying to use powershell?

What I feel Powershell does not give: short and simple command names, little syntax, and return values that are interpretable at a glance. And there's muscle memory of course, that's on me!
Every command has a short name.

A handy "punctuations" cheatsheet I found on reddit: https://www.red-gate.com/simple-talk/wp-content/uploads/2015...

Short aliases for all major commands: https://devblogs.microsoft.com/scripting/table-of-basic-powe...

Some commands have more than one alias, and you can set your own, of course.

PowerShell also has a very nice help system. For any commands that Microsoft provides, you can type : Get-Help Get-ChildItem

It will list all the various parameters, as well as the various aliases.

As far as return values, you can do $? or type out $LastExitCode - it works the same way you expect.

For a fuller help view you can type "help Get-ChildItem" (all commands and parameters are NOT case-sensitive - it does not care if you type LS or ls, get-childitem vs GET-CHILDITEM does not matter). I prefer this - it helps in remembering.

For me I genuinely think Powershell is fewer keystrokes than the equivalent terse bash. A lot of this is a question of heavily using history and editing old commands rather than writing new ones. And the old commands are legible so it's easy to tweak on the fly. Tab completion/history completion are really powerful. (You do need to enable PSReadline though, which is not out-of-the-box.)
I am a fish fan… but even fish has some difficulties, as many scripts and tools in the wild expect a bash-compatible shell. Otherwise, it is excellent and I use it on my computers 100% of time.

I guess other alternative shells like nu have about the same level of usability. If you like them, you can use them.

I use fish also but still default to bash and run fish manually when I log in. Then if I am trying to paste a command and it doesn't work right, I just type exit and run it in bash.
Probably best to use it as your interactive shell and still have bash or some other POSIX shell for scripts, unless they're intended for your personal use.
I use `fish` as my main shell. It's closer to POSIX than eshell or oil, but it's definitely not POSIX.

Personally, the main thing I like about it is that I can't copy paste bash commands. It forces me to read and understand and then convert. It also has some quality of life stuff I really like. I think next time I'm just going to go back to ZSH though as I feel I have learnt enough from the experience of using it that I'm no longer getting new things out of it, and I don't script in fish enough for the nicer syntax to be beneficial enough for me. Honestly, I prefer ZSH variables over fish variables too

I use fish too. My favourite feature is typing part of a command and using up and down arrows to cycle through the results, as opposed to ctrl+R and...I don't remember which one. Functions are easy to define too.
You can easily get bash to do that by adding these lines to your .inputrc file.

  "\e[A": history-search-backward
  "\e[B": history-search-forward
  "\e[C": forward-char
  "\e[D": backward-char
Not wrong, but fish is so nice because it just works without any configuration. Sane defaults are a blessing.

I just checked and the only things I have configured are `set fish_greeting` (i.e. empty) and some paths...

Edit: Also, I don't know how, but the fish completion is magic. It seems to remember which commands I use often in which folders and in which order. I'm not sure if that's how it's implemented. Sure feels that way though.

> It seems to remember which commands I use often in which folders and in which order. I'm not sure if that's how it's implemented. Sure feels that way though.

Check ~/.local/share/fish/fish_history!

Nice to know!

Nonetheless, what moved me from bash to fish was having this as granted. Now I worry only about specific higher-level functions. Also hunting each of these optimizations distracts me from my task at hand.

There's other stuff as well, for instance I'm abusing `for` iterations a lot more to run the same command for lists of things. Using bash before was less ergonomic and painful.

You need to restart bash to make this work. Cool.
Most things in fish can be achieved with customization and configuration in other shells, like zsh or bash.

The point of fish is a sane set of defaults that doesn't require customization and is good enough.

If you want zsh that acts like fish, try "fizsh".
That is so cool, people really think of everything don't they?
I checked fizsh out and the installation on Ubuntu was broken (from the package in the repo), the last commit to the repo was in 2016... It seemed promising at first but these things are all about continued investment and maintenance.
They are explicitly against configuration options though. Good luck if their opinions about what's sane doesn't match your own. By the way I have that feature in zsh myself. Quite useful.
> Good luck if their opinions about what's sane doesn't match your own.

Thank you, and yes, that's when you don't use fish.

The point of fish is being for people who are fine with the defaults set by the authors. It's the core selling point.

Fish shell search and suggestions are awesome, and not comparable to what readline gives you. I don't know how it does that, but the shell understands the concept of files, commands in PATH, and CWD. So depending on the directory you are in, after typing "vim " you will get different suggestions (completable by right arrow). Somehow it knows what I mean 80% of the time.
ctrl+R and...you keep pushing it to go back in time. In case anyone needs to know.
Another fish user reporting in.

I don't care too much about bash compatibility. I don't even care shell scripting in my shell - when I need to write a script I write a sh script (or python for more complex ones). I just want a shell that's easy to use and user friendly.

For some reason none of the other alternative shells "click" for me - I love the idea of having objects in my shell (like in nushell, or powershell), but all the implementations I've tried are just clumsy to use and get in the way. Whereas fish is awesome and works out of the box - barely need for any configuration/

Also a fish user, the lack of bash compatibility if required is easily fixed by bash -c, or just dump it into a script with a bash shebang but most simple one liners can easily be tinkered with to make it fish compatible - case in point `for` which just needs an end in most cases
It's gradually got more bash compatibility, with things like X=Y run-command, &&/|| as aliases for and/or, $() expansion, changes to * to match more items. I don't think it's impossible that a future edition of fish starts to support e.g. export or a subset of bash conditionals.
I'm fairly sure export is already supported, but I could be missing something.
Yup i've used fish too for many years because of it's excellent autocomplete. It's occasionally frustrating when you have to paste a bash command in, but if it doesn't work you can just spawn bash to run the command.
When there's something called deadline that's no longer feasible

    bash -c "" # to run some bash inline
or just

    bash -l # to jump to a bash shell

And that's not really a deadline issue. Sounds more of a planning one or an issue of not knowing your tools.
I've been using fish for at least a decade. While I can't simply run bash commands, I can easily drop to a bash shell and run anything.

The defaults and features are great.

Scripts I also write in bash, sh, or python for compatibility. It's not much of an issue.

I do remember something that used to break in my setup, but since I'm always in tmux, instead of changing the default shell (chsh -s), I just set the default for tmux to be fish.

    # set shell
    set -g default-shell /usr/local/bin/fish
I am still kinda bitter about mac os replacing the default bash with zsh. I gained nothing from that unwanted update, but got compatibility pains suddenly.

Is something is more complicated than a one-liner, use a real programming language instead, with proper building blocks, tooling and documentation. Use something like Go to crosscompile if you don't want to depend on something on the host machine.

In my experience, even very trivial short shell scripts over time tend to grow into a pain, that could totally be avoided when using a real language instead.

Believe the replacement was because bash 4 was GPL3 licensed, and zsh was not. It wasn’t so much for user benefits than it was for security and licensing.
They could have fix the security bugs.
I've watched a one line bash pipeline turn into a thousand line python program over the course of about a week. It didn't need new functionality, it was just not proper engineering to leave it in bash.

We never did agree on whether that was right or not. It was something involving digging information out of elf binaries where the python libs were much more verbose than the flags passed to readelf (maybe objdump, it was a while ago).

subprocess.check_call() is more verbose than bash, but probably a better option.
(comment deleted)
Try to use it as a daily driver. If you encounter a situation where there's a bug/weirdness/missing feature, you can always temporarily launch bash or whatever to do the one thing you need to do, then exit that (sub)shell and continue with the first one
I've been using fish for a couple years on my work laptops
How about instead of changing the shell get more out from your existing one.

Starship [0] and fzf [1] will make your life much easier in any shell.

I use fish but they work with bash, zsh and the like.

[0] https://starship.rs/

[1] https://github.com/junegunn/fzf

Why not both? I use starship and fzf with a fish shell.

Fzf is a great productivity boost, especially because it integrates with everything so well. Starship is... nice and flashy, but I don't think it actually improves my productivity a lot. The biggest feature for me is giving me the current git branch, and I used to do it with my fish theme. I mean it's nice to know what version of Python I have currently, it's just not a killer feature.

I use one fish plugin and it's a total gamechanger

https://github.com/PatrickF1/fzf.fish

Being able to instantly fuzzy find files, directories, git history, processes, environment variables and command history is like having a superpower.

Shameless plug for my plugin https://github.com/mk12/fish-fzf:

> Unlike the others, this plugin tries to pack as much as possible into a single "do what I mean" shortcut. Edit a file? cd to a directory? Just insert it into the command line? Many things like this can be determined from context.

I'm using Fish for years, tried Nushell recently, but it didn't click for me. While I like the principle of data being more than just plain text, it probably was just too alien to me.

A few here said they don't use Fish or another shell due to compatibility issues, but I wonder what the problem is: If I want to use a script written for another (POSIX) shell, it most likely has a shebang (or I can add it), so it will get properly executed using that other shell…

Mostly it's because you can't copy and paste stuff from blogs or Stack Overflow.
but you can just run `bash`, paste the command, and then `exit`?
I’ve used fish for years at work but that’s mostly a personal choice similar to your preferred editor. It’s more productive, but nobody else really sees it.

What’s helped a lot more has been replacing shell scripts with Python once they hit a certain complexity level. Huge reduction in code size, better functionality (e.g. it’s trivial to have good CLI argument parsing so people actually add it), and every time a large bash script has been converted some set of error-handling bugs has been fixed.

Im on Nu shell on Windows os. Im very satisfied with it
I think they're all fine (if they claim some sort of stability) with the proviso that you're going to occasionally want to drop into bash or something to check something out before committing it to a script.

(I assume you're talking about interactive use, not using them as the shebang line in your scripts. I wouldn't do that. But mainly just because then you need everyone to agree to install it, or to install it on your servers, etc.)

> Fish is probably usable, but outside of fish

I use fish, have for years, and I say the above to include it. Sometimes I'm not certain something works as I think it does (bash's myriad interpolation/variable manipulation techniques say) and so I switch shell to test it.

It does have bugs and weirdness of course, especially the vi mode, but it's not going to .. idk, rm -rf / when I only told it to rm -rf ~/.cache/* or something.

Nushell is great for simple tasks. i.e.

  ls **/data.json | each {|it| mv $it.name $"(dirname $it.name)/data.yml" }
Will be much more complex in bash

  find -name "data.json" | xargs -i bash -c "mv \"{}\" \"\$(dirname '{}')/data.yml\""
Note the escaped quotes and dollar signs in bash. It is really difficult to get them right.

In Nutshell we are actually using "functions" (supported syntax-wise) to do the job, so it will be much more simpler.

---

A more complex example from my recent code:

  ls $"(which npm.ps1 | get 0.path | path dirname)/*.ps1" | each {|it| get name | path basename }
    | each {|script_file| $"alias ($script_file | str replace ".ps1" "") = powershell.exe ($script_file)" }
    | str join "\n" | save --force ~/.config/nushell/env-generated.nu
Will be something like this in bash,

  find "$(dirname "$(which npm.ps1)")/" -maxdepth 1 -name "*.ps1" | sed -r "s/^.*\/([^\/]+)\.ps1/alias \1 = powershell.exe \1.ps1/g" >> "$NU_CONFIG_FILE"
Although the bash one is shorter, it takes me 10x more time to write and test. I initially tried to write it with xrgs but given up due to the complexity involved.

I think Nushell is more readable and easy to write for me.

> find -name "data.json" | xargs -i bash -c "mv \"{}\" \"\$(dirname '{}')/data.yml\""

Albeit this task needn't involve a shell at all - just `find` and `rename`:

    find . -name data.json -exec rename .json .yml {} +
In zsh you can use:

  for f in **/data.json; mv $f $f:r.yaml
Which is even shorter, and easier. In bash you need a bit more syntax:

  for f in **/data.json; do mv $f ${f%.json}.yaml; done
That second example can probably also be simplified a lot in a similar fashion.
I'm sorry but obviously you had to learn how to use nushell but you didn't learn how to use find (you don't need xargs) or bash (you don't need find).

Your first problem solved in bash:

    shopt -s globstar
    for f in ./**/data.json; do mv "$f" "${f%json}yml"; done
You can do it without globstar (without running into weird issues with newlines) like so:

    find . -name data.json -print0 | while read -rd '' f; do mv "$f" "${f%json}yml"; done
Now, since the particular problem doesn't require a shell at all, you can solve it entirely in find:

    find . -name data.json -execdir mv {} data.yml \;
Your second example would be:

    (
        cd "$(which npm.ps1)" && \
        for f in *.ps1; do printf "alias %s='powershell.exe %s'\n" "${f%.ps1}" "$f"; done
    ) >file
> Now, since the particular problem doesn't require a shell at all, you can solve it entirely in find: find . -name data.json -execdir mv {} data.yml \;

How do you do that without a shell?

IIRC running a command without piping/string semantics doesn't involve a shell, such as os.system() in python and child_process.exec() in Node.js.
I mean obviously you need some way of executing the command and you're probably not going to write a C program to call execve to do it, but the point is that it doesn't involve any shell features and aside from the escape syntax for the semicolon is completely shell independent.
I didn't learn Bash from scratch. I just serach Google/StackOverflow for similar questions.

But that is the point, there are too many commands to do the same job in Bash, each with dozens of flags. It is hard to learn them all, or even find the right command (like shopt, read) or flag (like -rd, print0, -execdir) in the first place.

That's why Nutshell will be simpler for small tasks.

No, the point is that if you go into a discussion saying: "X is better than Y but I should warn you that I never bothered learning Y but instead spent my time learning X" your ability to provide an accurate comparison is already put into question.

Then you go on and provide examples of extremely sub-optimal Y code and compare it to X code you wrote.

It's very uncharitable and very difficult to tell what is actually better. It doesn't matter if X or Y is better at this point because you haven't provided a fair comparison. And while I agree that bash is shit, I need a lot more than "here's some poorly written bash code compared to nushell" to persuade me to switch to something less ubiquitous.

Since bash and presumably nushell are both turing complete, there should be an infinite number of ways of achieving any task, what you want to compare is the shortest but so short that they're difficult to comprehend solutions, and there aren't that many. I can't tell if you picked the most idiomatic nushell solutions to your problems but I can definitely tell you didn't do the same for bash.

If you're happy to use nushell you would probably be happy to enable globstar in your shell. So my first solution would be comparable to your nushell version. And yes, you need to know what globstar is, just like you would need to know what nushell is.

Given that bash and presumably nushell both support running arbitrary commands the find version is actually shell independent and the fact that you don't know how to use find isn't bash's problem.

Let's put it this way, given I don't know nushell, I would also have to learn the iterator, lambda, and variable substitution syntax (each, ||, $v.name). I know how equivalents of those features work in bash (for, $...). I don't find your code any easier to read by default (without having to make guesses as to how nushell works). If I claimed right now that I find nushell syntax to be confusing, weird and unusual, would you think it would be fair for me to say that based on reading only your code?

You miss the part about them saying that the code is from stackoverflow so in other words not exactly hacked together.

Overall I agree with both of you but on different points, she'll scripting is an outdated painful process and yes we should provide optimal answers to be fair.

I don't think the code presented was taken directly from stackoverflow, and I don't think that's what the person I replied to said. That being said, even if it was from stackoverflow, stackoverflow is a poor resource for older languages/environments. There's still a major focus on points over quality answers and you get lots of bad advice from there.
(comment deleted)
Xonsh works pretty great. I've used it as a daily driver in the past but am trying out oh-my-zsh right now. Pathlib (and pathlib.glob) are pretty amazing, and python syntax is great for a shell.

https://xon.sh/

I've been using nushell for a couple of weeks and I'm finding it good enough for a daily driver. I was never much of a shell script person so I don't miss any bash-isms, on the contrary I find that I can easily perform some tasks I'd normally have fired up a Ruby REPL to do, both because the language is much more sane and because it handles structured data and file formats natively. As for normal shell usage (running commands) I definitely prefer it to bash, the completion UI is much nicer and you can set it up very easily for external commands. Also it supports Windows so I don't have to switch to powershell mode when I'm on my gaming PC.

Again, I'm not a shell script person and I never liked sh/bash so I don't have any 1000 line shell scripts that I'll be porting over to nu, and if I need to do something that would take more than a couple lines of code I'll switch to a proper programming language. I definitely wouldn't ship nushell scripts in production or for anything that isn't my local configuration because the commands and the language itself are far from having a stable API.

I've used bash/zsh for 20 years and I've been using nushell daily for work and personal projects since I tried it 6 months ago. It's fantastic -- you can do some really novel things that you would never normally do in a shell. But you do have to be prepared to invest some time in learning to do things differently from POSIX shells. The Discord community is very helpful.