71 comments

[ 3.0 ms ] story [ 133 ms ] thread
I used to love zsh and it's endless customisation options, it definitely felt more robust and sophisticated than bash as a shell and was my preferred daily driver.

Then I discovered fish and to be honest the sane defaults and out of the box functionality means I haven't looked back in a few years now.

If fish didn't exist, I'd absolutely still be using zsh with Zim or presto.

As far as I know, fish is not compatible with bash scripts ( most legacy stuff) and this makes zsh attractive.
I don't get it. Are you executing extremely convoluted bash one liners at your shell prompt?

I still write for bash and use a bash shebang to run it when I need to script. Mostly because the likelihood a colleague or whoever else comes along later happens to be using fish is pretty low. Bash remains the most portable option!

I tried fish and uninstalled it because nothing from stackoverflow worked.

Sure, I could spend time learning the fish syntax. But I won’t, since zsh works.

I see. I just dump that kind of stuff in a bash script or bash -c '...' it directly if necessary.

Still, to each his own! That's the great thing about having a glut of viable options.

I often find I write out a series of commands interactively in the shell, then decide I want to save them as a shell script, which I might then want to share.

I enjoyed fish, but found it too annoying to have to translate things into bash when I wanted to share them.

exactly, that's why im back too.

back to zsh from fish, that is.

A lot of CLIs don't ship with fish autocompletion :/
Generally my workflow when developing scripts is running individual commands on the CLI so I can see what it's doing so I can get it right. This is not possible with fish unless I start a bash shell, so at that point, what is the point? With zsh, most of the code I would run in a bash script still runs in a zsh interactive session. Sure there a few edge cases, but they're quite well documented.
Generally my workflow when developing scripts (in Python) is to run individual functions in the repl so I can get it right.

This isn't possible with bash unless I start the python repl, so at that point, what is the point?

Hey, it's possible you spend a lot of time writing scripts, and they need to be bash compatible. Zsh is great for that.

Just wanted to reflect how made-up this sounds to those of us who treat sh like any other language.

> Generally my workflow when developing scripts (in Python) is to run individual functions in the repl so I can get it right.

As a matter of fact, this is exactly what I do when I write Python scripts too. It helps understand exactly what things do quickly and figure certain smaller things.

> Just wanted to reflect how made-up this sounds to those of us who treat sh like any other language.

What do you think sounds made-up?

I mean that "can't use fish because I have to use bash to write bash" makes about as much sense to me, given how I use the terminal, as "can't use fish because I have to use python to write python".

I'm assuming that means you write more shell scripts than I do, or think of the context switch between shells as qualitatively different from the context switch between shell and (some other) repl. All of which is fine.

From the fush documentation:

  Special variables

  Some bash variables and their closest fish equivalent:
    $*, $@, $1 and so on: $argv
    $?: $status
    $$: $fish_pid
    $#: No variable, instead use count $argv
    $!: $last_pid
    $0: status filename
    $-: Mostly status is-interactive and status is-login
Replacing «$$» with «$fish_pid»? A contentious choice at the very least – does it also apply to non-interactive fish scripts? «…use count $argv» instead of «$#» – why? Both, $$ and $#, are non-bashism's and go way, way back into the UNIX prehistoric times – hardly bash-ism's.

Fish does not appear to have basic conditional variable expansions, matching affix removals and pattern substitutions, either; i.e. ${_var:-substitute}, ${parameter<# / ##>word}, ${parameter<% / %%>word} and ${parameter/pattern/string}. Or, at least their nearest equivalent are not prominently featured in the documentation.

How often do you type these things in an interactive shell though? Also things like $status and $argv are reminiscent of csh, which also goes back a long way!
With a varying frequency but I do use them in interactive sessions:

  $ grep -c '\$\?' ~/.history
  137
  $ grep -c '\$\$' ~/.history
  30
  $ grep -c '\$!' ~/.history
  6
  $ grep -c '\$#' ~/.history
  13
Less so when it comes to affix removals… I use them liberally in scripts as well as in data transformation pipelines or more complex one-liners, though.

I also semi-frequently quit the shell with «kill -9 $$» when I do not want to pollute the shell history with garbage, which is not refelcted in the count above for obvious reasons. It is quick and efficient.

> Also things like $status and $argv are reminiscent of csh, which also goes back a long way!

Ah, I thought somebody would mention csh as the prior art! Frankly, the C shell syntax have never really clicked with me precisely because of the more verbose syntax, and, as soon as other shells have borrowed history, job control, aliases and a few other features from (t)csh, I was out of the house!

Ah right; I never do that kind of stuff.

I wonder if you can set "$$=$pid" in some hook in fish (I don't use fish, or even like it for that matter, albeit for different reasons).

Longer names like $status and $pid are actually nicer in scripts IMHO, I typically use those in zsh (which often supports for csh-ish long names and Bourne short names) scripts as it's just a bit clearer. Same with short (-q) vs. long (--quiet) flags: short is great for interactive CLI, long often nicer in scripts. especially with lesser used flags.

Yes, zsh – which has been my daily driver for more than two decades – offers the best of both worlds, long and short names for most of the useful variables, but those do not affect the [expected] core shell functionality.

I suppose, I should have made my point clearer earlier on. A UNIX shell (along with the terminal) is such a fundamental tool that a substantial departure or a paradigm shift from long standing foundational conventions or from the familiar syntax had better bring at least a tenfold increase in productivity for me – to substantiate the said departure. Then I will happily change my workflow and retrain my muscle memory to adapt. scsh is the only other shell that came close to that at some point in space and time, however, it seems to have perished into the oblivion.

A new shell with reasonable and more new user friendly defaults at the expense of missing core shell features does not reach the tipping point for me.

bash isn't compatible with python either, unless you use #!/usr/bin/python or the like.

All my shell scripts start with #!/bin/sh, so the language my user shell runs is irrelevant. Sometimes I do have to preface copypasta with "bash" and end it with "exit", but it ain't the end of the world.

There are a bunch of good reasons to prefer one shell over another, this isn't one of them.

Indeed, just use the shebang #!/bin/sh (if it's posix sh), and #!/bin/bash if you must use bash functionality. There is no reason to not use a different interactive shell.
Please use #!/usr/bin/env bash if you're using bash. It seems more common to have env in /usr/bin than it is to have bash in /bin. On BSD systems, bash is often in /usr/local/bin, and on macOS the user often has a more modern bash in /opt/homebrew/bin or other package manager directory.
> bash isn't compatible with python either, unless you use #!/usr/bin/python or the like.

You're rather aggressively missing the point.

If you need to write and maintain bash scripts but use fish as your command line, you now need to know the idiosyncrasies of both shells ...

If you want to write portable scripts and use a reasonable interactive shell, you need to know two shells anyway. Scripts should ideally be written to only use shell features defined in POSIX, since bash isn't available on every system. It's available pretty widely, but not on e.g. Alpine Linux by default, and the version on macOS is so ancient it doesn't have features like wait -n.

Unless you're going to use rlwrap /bin/dash as your default interactive shell (please don't) you need to know both your interactive shell and standard shell if you're going to write portable scripts.

> Scripts should ideally be written to only use shell features defined in POSIX, since bash isn't available on every system.

I don't write system scripts that need to run on systems without bash and have not needed to do that for a long, long time.

Ha! Funny, I just switched _back_ to Bash because I found ZSH so flakey and amateur.

I tried for years to like it, even tried oh-my-zsh, and fine tuning myself. Finally got fed up with its laggy "smart" crap and went back, and oh man am I happy I did. Everything works, it works fast, and it does exactly what I tell it to and no more.

My experience id aldo the zsh is slow compared to bash. I am using the defaults from Apple on an M1 with some minor modifcations.
On raw defaults, I find it hard to see that you can do anything with either bash or zsh where the shell itself does anything where you can even notice a delay. Things like basic file completion or history searching are basically instant. For scripting there are plenty of benchmarks out there and zsh typically beats bash but both are beaten my minimal shells like dash.
You don't need to use oh-my-zsh and "laggy smart crap" though; it works just fine without it.

I don't have most of the advanced features enabled, except that listing completion options doesn't push text up, which I found really useful after I got used to it. As well as being able to navigate it with the arrow keys. I never noticed it's slow, and I used zsh on a Pentium N-something budget laptop that definitely wasn't fast.

I think you're judging zsh based on third party add-ons or non-default config. You can make bash flaky and amateur that way too.

Stock zsh is neither though. It's quick and solid. No surprises.

Ditto with Vim/Emacs/VSCode/etc. All of them can be slowed to a crawl or be unpredictable with plugins.
Yeah, one shouldn't be judging the performance and stability of zsh based on oh-my-zsh of all things. oh-my-zsh is one giant mix of everyone's configs, which severely degrades performance and stability. It's for people who want most features out of zsh in the quickest way possible. Those who prefers an optimized config would be better off configuring zsh themselves. Even getting the autocompletion right would provide a great QOL improvement over anything bash can provide, though it's unfortunately a bit trickier to configure than is ideal.
Unfortunately, it doesn't get you most features out of zsh. It leaves a lot disabled too. It turns on the included completions, adds flashy prompt themes and a pile of aliases that you still need to learn if you want to get any benefit from them. Key bindings are largely left untouched with none of the advanced widgets.
I don't know, I mean I got rid of all that oh-my-zsh stuff and tried configuring it lean, too.

An example of the flakey feeling I'm talking about is the way auto-complete works. I hit tab, and it does a fuzzy suggestion? Then when you're done with the suggestions and picked (or not), they disappear? Or just the fact that auto-correction exists at all? Okay these things are subjective, and maybe not exactly "flakey", but they make if feel like that to me.

Interestingly, I just took _all_ configuration out and tried it, and startup was blazing fast! It looks like whatever was slowing it down is actually in my Bash configuration (which I also load in ZSH). Doesn't slow down Bash startup though, wonder what it is :P

I switched from zsh/oh-my-zsh to fish mostly because fish does everything I want for an interactive shell and is simply one package from my package manager.

With frameworks like oh-my-zsh I'm always worried about supply chain attacks.

I do use https://starship.rs (which is also a package away), and I think things like fisher https://github.com/jorgebucaran/fisher are useful when you need a specific fish script.

I also don't really like writing zsh scripts because I always run them through https://www.shellcheck.net which works best with posix sh/bash

What do you use as terminal emulator? I Switches from iterm2 to kitty and omz to starship. It is for sure faster now to start the terminal, even running commands has different response time, visible to the eyes.

Could I ask How does fisher come into play if you have something like starship already?

Is it worth sacrificing a small speed increase for the myriad of plugins omz offers ?

I am not really sold on the idea of why I should switch.

This seems interesting, and is likely use it if I hadn't already got a setup that I like with antigen.

Nice project.

How does it compare to ohmyzsh with p10k?
Beware Zim is a historical and still alive desktop Wiki GTk-based...
Zim is also an invader trying to take over the planet. Luckily we have the boy with the large head to stop him.
Actually in a distro package manager you might have issues to name packages if they share the same name.
I use zplug, and wrote a quick doc on getting zsh+oh-my-zsh+zplug+powerlevel10k+fzf up and running on MacOS: https://gist.github.com/aclarknexient/0ffcb98aa262c585c49d4b...

I'm sharing that not as blogspam (it's a gist, so I don't get anything for sharing it) but because every time I show someone fzf plus the tools mentioned above, they always ask for a guide on installing it.

Anyone know how this compares with Prezto which also bundles powerlevel10k by default?
Is anyone else mostly rolling with the zsh (not oh-my-zsh) defaults?

After so many years of using Bash I switched to zsh almost a year ago. I use the vanilla zsh set up with 2 plugins:

- https://github.com/zdharma-continuum/fast-syntax-highlightin... for very good and fast syntax highlighting

- https://github.com/zsh-users/zsh-autosuggestions for auto-suggestions

I don't use a plugin manager, instead I put together a ~20 line shell script[0] which handles either cloning or pulling plugins, then you can load them in your zshrc[1].

I haven't found the need for anything else and my whole dev environment is based on using tmux, terminal Vim, etc.. Basically I spend a lot of time there in my day to day. I started with the idea of "less is more" and planned to add more things over time but the time to add new things hasn't come yet.

[0] https://github.com/nickjj/dotfiles/blob/0076e508403c9981e393...

[1] https://github.com/nickjj/dotfiles/blob/0076e508403c9981e393...

>Is anyone else

Yes. Minor thing but I find this sort of passive aggressive framing more irritating as I've gotten older and crustier. You're on a global network of billions. No matter what it is about something with as much uptake and variation as shells or millions of other things, of course there are definitely other people doing the same as you. Rather than a kind of silly/weird seeking of validation just assert what you do and why. It's particularly galling when yes you're probably in the flat out majority overall, defaults are powerful and there are almost certainly a lot more people who just dip into shells once in a long while and never customize a single thing than who go even as far as you do.

>mostly rolling with the zsh (not oh-my-zsh) defaults?

You could ask the same thing about all sorts of powerful tools and environments, from powerful CLI tools (not just shell but Vim or Emacs) to CAD and graphics programs which are famously adaptable, and the answer is always that it's a matter of an individual finding their comfort place on a spectrum of tradeoffs between ease of moving between environments and meta-work cost vs future efficiency/comfort benefits. The more one customizes to their exact needs, the more fragile the environment in moving across systems (efforts in portable environments can help on the technical side though they're not a panacea, but even that won't help with just plain not being allowed to customize a remote work area). It also means when outside of the heavily customized environment productivity may drop quite a bit, a lot of muscle memory goes to things which aren't there. It also takes meta-effort, time and resources spent on improving tools themselves rather then using the tools to do the desired tasks one reaches for the tools in the first place. Of course, some level of effort is required by any specialist to learn at least standard tooling and knowledge, but rarely is mastery of a tool an end in and of itself vs a means to do something else with said tool. Ideally there should be a positive ROI on time invested vs making that back later, but that won't necessarily be the case with something rarely used or where needs are basic.

Conversely though customization, getting really comfortable with the full power of automation computers offer and knowing how to rapidly match that to any new work can have major productivity boosts down the road. And sometimes give new perspectives on the edge cases and other tooling that is useful anyway, as well as just plain make things better fit individual needs and senses. And some people just don't move beyond their own environments much, or are valued specialists who would be allowed to bring their own environments and tool chains with them at any new job (encouraged/expected to even, that's part of the productivity they're being hired for).

No right answer to that now anymore than there was 10, 20 or 30 years ago. Personally I'm more towards the customization end of the spectrum when it comes to shell and general CLI environment, I'm not doing a lot on machines I don't at least have user environmental control over vs my own systems, and I've been happy to sink the time into really shaping zsh and other utilities to what I want. But I'm not nearly as far along as a range of other people either and I can certainly see the attraction of just using the standard stuff (and I do do that more in other areas than when I was younger too). Deviation has a cost and it's worth giving a bit of thought as to whether the cost is worth it. So nothing wrong at all with using something pure vanilla or close to it. But on HN in particular shouldn't be surprising if a lot of us do a fair amount of tweaking. And then search for a way to make that reproducible, sharable and clean to work with same as any other "software project", which leads in turn to various frameworks and such to help with that.

Passive aggressive is a super weird accusation here. Having read a ton of (and posted a few) "does anyone else" type responses generally, I fail to see why they should be read as anything other genuine curiosity as well as conversation openers, perhaps to tweak said flow.
> perhaps to tweak said flow.

Yeah, that was the goal of my opener.

I'm happy with my set up but there's always "unknown unknowns". I use like 50 Vim plugins but never felt the urge to add more functionality to my shell because it feels great as is with just the 2 I mentioned. I was hoping maybe someone would suggest something really useful that I wasn't aware of.

Personally, I'm more peeved by the "am I the only one" framing.
But why? Again, not unreasonable to start a conversation like this? "It feels like a whole lot of people are doing something in way X, but I like way Y, which seems simpler and more obvious to me?"
Upvoted this and all the others, including OP's sibling comment. I hope nobody downvotes anyone either way, and I should have put that at the end vs in order since it's just my own feeling on the phrase and it wasn't like this post in particular was in any way a particularly egregious example, just one of those straws on the camel's back that happened to get to me. Apologies to nickjj.

But I don't agree with you that the phrase can't be read to have those connotations in general, and it feels like it's been becoming more frequent.

>"Am I the only one out of billions of humans who does a obviously pretty common thing" (like sticking to default values which by definition are default because whomever set them thought they were a decent starting place)

kind of feels irritating the more I see it vs some sort of

>"Does the effort in setting this up and number of moving parts/dependencies it adds really justify itself, or is it more for fun/learning? I'm quite satisfied with my [vanilla+ setup], what does this bring to the table and at what point is it worth sinking more into these tools if ever?"

or even

>"Though this and similar projects are interesting I think most including myself are better served staying as close to defaults as possible."

100% though: this may all be subjective subculture and learning. I can see how it could be treated as an innocent opening phrase, just a form without any deeper meaning. It rubs me the wrong way though anyway, there is a defensiveness about it. Like even, what if you were the only one? So what? You can still be right for yourself anyway. How many other people are that way or not seems both peripheral and distracting (bringing in social pressure) from the meat of it.

Anyway, Sunday morning HN procrastinating from fighting with getting some crufty old infrastructure running on a new vm platform! Very genuine apologies as well that picking on that nit clearly irritated a bunch of other people in turn! There was nothing wrong with the question content, it's certainly something I've grappled with and not always well in either direction. In the past I've spent way too much time diving deep into things that I barely ever used later, or conversely cruising along for years without fully learning a tool that could have saved me enormous time by automating stuff I did manually. I know there is advice along the lines of "if you find yourself doing this tiresome manual task for the Nth time now it's time to figure out how to automate it" or even tools that themselves track your usage like the open source ActivityWatch [0]. Run that for a year and see where your time is going. I never learned or did any of that early on though and still struggle with the tradeoffs there.

----

0: https://github.com/ActivityWatch/activitywatch/

> silly/weird seeking of validation

Relax! we are just humans, we want to connect.

And what's the problem for seeking validation? Isn't it in our nature?

> Minor thing but

You might be over-interpreting the phrase.

Novelty drives "news", including here on HN. Every now and then you see a post to a generic product page. Usually after a big release. And the inevitable comment is "what about it? I've been using it for years".

So naturally we see more articles about new-ish or lesser-known modifications to core tools. E.g. zsh. An article about Oh-My-Zsh would even attract the eyerolls because it's so popular and well-known among the commentariat here.

I speculate that GP was saying "Is it just me, or are others pretty happy with the original that does not merit a post here? Am I missing something awesome from the novelty bucket?"

If GP was not saying that, then I will!

I've run zsh and vim and tmux for ... very very long times, though obviously varying between tools.

In all cases, I run them with largely stock config, only minor changes and customization. Vim has a dozen lines of config plus a few custom file formats, tmux gets a hundred lines or so of config, zsh gets functions and aliases. That's about it.

I check out all the novel bits, sometimes even test them. But I always come back to stock with my minor config.

So yes, stock zsh is 100% adequate for intensive daily use. Some people put spoilers and pinstripes on their cars. I do not.

I didn't find that phrase passive-aggressive at all. I found your verbose ramblings to be a huge distraction from the conversation, though.
I’ve switched away from using OMZ as an all-in-one framework that takes over my .zshrc, but I still use some of its plugins. Its plugin management is too slow for my tastes, but there’s a few plugins that I came to rely on.

Switching to Sheldon [0] has given me the best of both worlds.

[0] https://github.com/rossmacarthur/sheldon

(comment deleted)
I use zsh4humans, which is close to vanilla, much much faster than ANY other framework and still allows to easily import and update plugins/completions.
I'm tempted to reply that I went back to using "vanilla" Zsh, and just added stuff to my awesome repo which is only 3.9KB minified and gzipped.

But not yet.

I cannot use a new machine without this excellent zsh theme https://github.com/spaceship-prompt/spaceship-prompt

And I've way too many plugins

# Add wisely, as too many plugins slow down shell startup.

plugins=(git node npm fnm yarn vscode ag brew aliases alias-finder autojump )

plugins+=(macos battery colored-man-pages command-not-found common-aliases copypath copyfile)

plugins+=(zsh-navigation-tools zsh-interactive-cd web-search frontend-search z per-directory-history)

plugins+=(postgres gh github git git-auto-fetch git-escape-magic git-extras gatsby gitfast gitignore)

plugins+=(zsh-syntax-highlighting k)

I've been using it for years and it's simple to configure and fast.