Hacker News new | past | comments | ask | show | jobs | submit login
Fish – A friendly interactive shell (github.com/fish-shell)
252 points by keepamovin on Aug 26, 2023 | hide | past | favorite | 162 comments



Best part of fish is how little config is needed. I’m 41, married with kids. Old AF by some standards. I have zero patience with wasting my time configuring tooling.

zsh felt like it fought me every step of trying to configure it to be halfway decent. And a lot of zsh scripts out there aren’t exactly bulletproof. It shouldn’t matter, except for the fact that if you use the shell with any regularity you will inevitably bump into edge cases that weren’t handled well by a mishmash of user scripts whose provenance is mostly copy/paste with little understanding of why it is all needed.

Here’s my fish dotfiles:

https://github.com/mattgreen/dotfiles/tree/master/fish

It has a submodule based plugin system (loader in conf.d), an async git prompt, my aliases, and a few env vars set. It needs no maintenance because fish provides almost everything already.

The only thing I want from fish at this point is to make async prompts first-class. They are best handled by the shell, not user code, due to the state tracking.


I use bash and also have no patience for configuring tooling. Your fish dotfiles are more complicated than my bash ones. I used to work on a team where many of the other engineers used fish. I never saw it doing anything I couldn't do in bash, although it looked a little fancier. But the annoying thing was when they asked me for help, and none of the commands I gave them worked in fish. It made for very slow troubleshooting sessions.


Fish has so many more features out of the box than bash. Once you use fish for a while it's really quite painful to go back to basic bash.


i am using fish for more than a decade and i don't have any dotfiles for it. (do i win? :-p )

your commands to help not working in fish? that is rather surprising. i would think that fish users should be aware that shell specific things in fish are different, so they should have been able to cope and translate as needed.

and it's not what you can do in fish that makes it special. it's how you do it. the syntax coloring, the completions, the syntax itself...

the key thing for me is how it handles searching history and autosuggestions. i just learned how to somehow recreate this setup in zsh, and i am very curious if bash can do that too: https://news.ycombinator.com/item?id=37274207

btw i believe bash got a lot better at command completion after fish popularized the idea.


Atuin or fzf is well worth adding to fish. I only add one of those (atuin these days) and a few custom scripts to make my life a bit easier.


The couldn’t just open a bash shell? It’s not like installing fish removes bash from your system


I went through the initial config wizard of zsh exactly once, almost a decade ago[1]. It took me maybe 5-10 minutes, and even though I don't fully understand what each command means, I haven't modified it in all this time, and it works well. I really don't think this was any significant waste of time or tedious task - I was just as free to simply ignore it.

Most of the remainder of my zsh config are prompt utilities and other things I've added over the years. I don't use or really need any plugins, though if I needed, last time I tried zplug it was really easy to set up and use.

[1]: https://github.com/mid-kid/config/blob/master/shell/.zshrc#L...


I use Oh My ZSH out of the box. It’s pretty cool https://ohmyz.sh/


Agree with everything you said. If I didn't have to write /bin/sh compatible scripts for work, I would switch to Fish for similar reasons. From a UX point of view it's indisputably ahead of every other shell and it isn't even close, to the point I'm surprised it hasn't been adopted as the default by an OS like Mac yet. I can walk my family members through terminal things with Fish and nobody gets frustrated or quits. I can't say that about other shells.


You can just put a bash shebang at the top of the script and use it just fine under fish


> zsh felt like it fought me every step of trying to configure it to be halfway decent.

oh-my-zsh is a lifesaver here. I have a very small dotfile that delegates most of the config to omz, which I have in a bare repo that I clone onto each new machine. It took maybe an hour a few years ago to settle on the plugins I wanted and put the repo together, and each new machine now takes 5-10 minutes to get up and running.


OMZ is what drove me away from zsh. Fired up a prompt while working one day and it was asking if it could check for plugin updates.

Really feels like OMZ doesn’t know its place when it is configured by default to do that. Tools should be quiet and keep to themselves.


that's really easy to turn off if you're happy with your setup.


If I already have zsh set up to my liking, what improvements/changes, if any, would I experience if I switched to fish?


I would say it has a "better" scripting languages syntax.

For example, compare this in zsh:

``` case $input in "foo") echo "Input is foo" ;; "bar") echo "Input is bar" ;; ) echo "Input does not match any case" ;; esac ```

with this in Fish shell:

``` switch $input case "foo" echo "Input is foo" case "bar" echo "Input is bar" case "" echo "Input does not match any case" end ```

And it was a really small example. Fish can do much more with "simpler" and not arcane syntax.

Fish also has `string` to work with string much much easier [0].

You miss `oh-my-zsh`? Fish has `oh-my-zsh` [1].

You miss integration with `fzf`? Fish also has it.

One caveat is Fish is not POSIX-compatible. But I don't find it a compelling reason to not using it.

Personally, I use Fish as my main shell. I do use zsh/Bash in my company though since they're more ubiquitous.

[0] https://fishshell.com/docs/current/cmds/string.html

[1] https://github.com/oh-my-fish/oh-my-fish


Very helpful, thank you. Was not aware of most of these aspects. Definitely curious to try fish now. Thanks!


Your fish dotfioes are a lot more extensive than my extremely small .zshrc file. What have you configured it to do?


I've been using Fish as my login shell for more than a decade now. Unlike many other commenters here, I also use it for scripting. For simple stuff, it's way nicer for writing scripts because the language just has has fewer gotchas than bash.

If you're just reading instructions online, translating between examples given in bash and fish is trivial. I see people talk about that being an issue for them and I don't understand it; it's literally never given me trouble.


The one thing that keeps me from using it more often for scripting is the lack of a fail-on-error mode (similar to `set -e` on bash). I know it is hard to get this to behave well in all cases (e.g. pipefail) but I don't want to do much scripting without it.


The other ones that annoy me are shell redirection from fish functions and some job control issues, which I'm hoping will both be fixed when job control is rearchitected as part of the ongoing Rust port.

I still use bash in CI, and for Linux scripts that I distribute to others. For macOS automation, I use zsh since it's the default nowadays.

My fish scripting is mostly for personal use and occasionally little wrappers on servers that I own. Sometimes I'll share a bit of fish code with other fish users at work, too.

Fail-on-error would be nice and help make the case for using fish in more places. At organizations where no one really knows bash that well anyway, fish would actually be nicer for scripting than bash if it had just a few more goodies like that imo.


I've used fish for about 5 years now, and I don't really wanna go back. Out of the box, without any addons at all, it does everything my old zsh setups did, with a package manager and plugins. The only change I've made to it was spacefish (now starship.rs)


Same story here. But I recently moved to Tide prompt. It's pure fish and really amazingly fast.


You may also want to try z, and, err... I don't have my config with me, but I have a plugin that notifies me if a long-running background command finishes, which is really handy.


What are your use cases for starship? It looks interesting but I think I'm missing the imagination necessary to use it to its full potential.


I use starship with zsh. The biggest value is showing the current environment for any project without any config. Shows the active node version, Python venv, k8s context, all without having to think about it.

The other day an AWS command was rejected with a generic 403 error and at a glance I realized I'd forgotten to switch the default profile—without starship I suspect I would have spent a while troubleshooting my SSO login instead of just switching profiles.


I also use starship with barely any custom config (like fish). It shows me the environment I'm in for a project, including which versions of tools are active and which server I'm currently connected to (if any). And it looks pretty enough.


Big one for me was out of the box support for showing current kubernetes context. Very helpful if you work in multiple kubernetes clusters and in particular if you move around namespaces helping others.

Doable with configuration and either lots of work or plugins in other shells but the combo of fish + starship.rs offers a lot for little setup.


Not OP, but I use Starship with fish and bash, it shows me my git repo's status without having to run `git status`, which is very useful for me.


The use case for me is a prompt that Just Works. No need to hack $PS1 or anything else, I just install it and everything works.

There are some optional bits for more niche things (like laptop battery) you can enable with a config file, but it’s not necessary.


Does it have support for reverse search yet? Not interested in auto complete.


Maybe the recent ctrl-r behavior changes: https://fishshell.com/docs/current/relnotes.html#fish-3-6-0-... do what you want?


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

Can also do cool stuff like search for a file to open in $EDITOR and searching git log


I end up installing mcfly (https://github.com/cantino/mcfly) in all my shells, and it works great in fish as well.


There's also fzf.fish, the only plugin I use.

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


Same. A shell without fzf now feels weird.


you just push ctrl-r just like in zsh


type something, press arrow up


Good luck with that if what you’re looking for is in the middle of the command, though


I can search for just an argument and it finds the whole command fine


Fish will match the string even so.


Fish explicitly handles that case


Did you have to convert your scripts to fish? Or is there an automated way?


Nobody (I know) that uses fish actually writes scripts in fish. Everyone writes scripts in bash for portability.


I’ve been writing all my shell scripts as .fish files for years. They’re just for me and I enjoy the syntax.


Same! I love the syntax, and I only share my .fish scripts with a friend or two I program with that also uses fish.


I’ve used fish for a half decade too, I still write my scripts in bash like everyone else. I want them to be standard and portable.

Longer scripts get the Python treatment or a Go application.


While there is a tool called `babelfish` that will automatically convert bash to fish, in practice it's rarely needed.

You can run bash scripts from fish.

For sourcing, often it makes sense to use direnv to automatically load variables. -- For "just source this one time", in the worst case you can run a bash shell, source that, then run a fish shell.


You can always run .sh scripts


As it has been a while—related threads. Others?

What's Happening with Fish Releases? - https://news.ycombinator.com/item?id=36875727 - July 2023 (1 comment)

My shell setup with Fish and Tmux (2021) - https://news.ycombinator.com/item?id=35672358 - April 2023 (80 comments)

Ask HN: Are alternative (oil, nu, etc.) shells usable as daily drivers? - https://news.ycombinator.com/item?id=34722208 - Feb 2023 (141 comments)

Rewrite it in Rust - https://news.ycombinator.com/item?id=34588340 - Jan 2023 (464 comments)

Fish 3.6.0 - https://news.ycombinator.com/item?id=34298157 - Jan 2023 (23 comments)

Fish Shell 3.5.0 - https://news.ycombinator.com/item?id=31768405 - June 2022 (71 comments)

Fish 3.4.0 - https://news.ycombinator.com/item?id=30734072 - March 2022 (90 comments)

Fish 3.4.0 Released - https://news.ycombinator.com/item?id=30660587 - March 2022 (21 comments)

Ask HN: Oil or Fish Shell? - https://news.ycombinator.com/item?id=30154652 - Jan 2022 (2 comments)

The fish shell is amazing - https://news.ycombinator.com/item?id=29341390 - Nov 2021 (290 comments)

Nsh: A fish/bash-like Posix shell in Rust - https://news.ycombinator.com/item?id=28967257 - Oct 2021 (50 comments)

Fish Shell 3.3 - https://news.ycombinator.com/item?id=27663637 - June 2021 (1 comment)

Fish shell - https://news.ycombinator.com/item?id=27180420 - May 2021 (118 comments)

Fish Shell 3.2 - https://news.ycombinator.com/item?id=26302678 - March 2021 (128 comments)

Fish is not operational on a VT220 terminal (2015) - https://news.ycombinator.com/item?id=25526237 - Dec 2020 (113 comments)

New Features in the Fish Shell - https://news.ycombinator.com/item?id=24631138 - Sept 2020 (138 comments)

Dolphins learn from their peers to use empty shells to catch fish - https://news.ycombinator.com/item?id=23660910 - June 2020 (8 comments)

Fish Shell 3.1.0 - https://news.ycombinator.com/item?id=22314671 - Feb 2020 (1 comment)

Fish: A command line shell for the 90s - https://news.ycombinator.com/item?id=21361696 - Oct 2019 (83 comments)

Show HN: Fisher 3.0 – the package manager for the fish-shell - https://news.ycombinator.com/item?id=18920972 - Jan 2019 (1 comment)

Fish shell 3.0 - https://news.ycombinator.com/item?id=18776765 - Dec 2018 (220 comments)

Fish: A user-friendly command line shell for macOS, Linux, etc - https://news.ycombinator.com/item?id=15910897 - Dec 2017 (204 comments)

Fish (Shell) for a Week - https://news.ycombinator.com/item?id=14422672 - May 2017 (2 comments)

Why I'm Hooked on Fish Shell (and How to Set It Up Right) - https://news.ycombinator.com/item?id=14417046 - May 2017 (1 comment)

The fish shell is awesome - https://news.ycombinator.com/item?id=14179081 - April 2017 (7 comments)

Fish Shell Design Principles - https://news.ycombinator.com/item?id=11102941 - Feb 2016 (71 comments)

Fish shell 2.2 - https://news.ycombinator.com/item?id=9873090 - July 2015 (70 comments)

Fish shell - https://news.ycombinator.com/item?id=9566441 - May 2015 (182 comments)

FISH Shell: A dynamic shell - https://news.ycombinator.com/item?id=8783150 - Dec 2014 (3 comments)

Fish shell 2.1 - https://news.ycombinator.com/item?id=6626635 - Oct 2013 (151 comments)

fish shell - https://news.ycombinator.com/item?id=6224524 - Aug 2013 (75 comments)

Fish shell 2.0 - https://news.ycombinator.com/item?id=5723235 - May 2013 (175 comments)

Fish 2.0 shell beta - https://news.ycombinator.com/item?id=5567639 - April 2013 (56 comments)

Fish: Finally, a command line shell for the 90s - https://news.ycombinator.com/item?id=4073162 - June 2012 (146 comments)

Fish sucks (but your shell sucks more) - https://news.ycombinator.com/item?id=2031110 - Dec 2010 (60 comments)

Fish - The friendly interactive shell - https://news.ycombinator.com/item?id=820677 - Sept 2009 (16 comments)

Fish Shell: A User-Friendly Shell or Like a Heavily Customized zsh - https://news.ycombinator.com/item?id=811113 - Sept 2009 (8 comments)


I think https://news.ycombinator.com/item?id=23660910 may be a trap street^wlink to see who is watching :)


Right! I upped the ante from https://news.ycombinator.com/item?id=29343065 by taking out the j/k


Haha, Good one! :)


I tried zsh at some point, but I got the impression that it's basically the same as bash out of the box, and you need to spend time customizing it to see the benefits. I don't want to spend time customizing my shell, I want it to work out of the box.

Fish is noticeably better than bash out of the box, with absolutely no customization. Magic autocomplete is life-changing.


I was using fish on Ubuntu in college. First job gave me a macbook and I set it up using fish. We only had one devops guy and he shared the app set up docs and all the scripts were available only in zsh or bash. I was okay with switching to zsh tbh. But the dude stopped me and then spent half a day learning and then updating all the docs with fish scripts as well! Bless him!


What I like about fish is that it provides a lot of nice-to-have ergonomic features from the get go without having to install plugins.

I add starship.rs to it and fzf integration but that's it.


Wouldn’t that also be the two things one would do in bash?


This is true. However I was calling out, wrt fish, the only two additional "plugin" type things I add in order to have a comfortable shell environment.

Fish conveniently provides history based autocomplete so I don't need to setup some plugin for that.


Why do you need starship.rs?


You don't need it. But it's just a really good, no-bullshit, customizable prompt, and you can use it with basically any shell you like, drop-in


Yeah. I love the default starship and install it on every shell I use, currently PowerShell + fish + bash. It shows me all kinds of useful info like which k8s cluster I'm logged into, which AWS/Azure/GCP account, whether the current directory has uncommitted git changes...


I think I misunderstand what "prompt" is referring to here. What is it?


When you open a new shell, by default it'll say something like `user@hostname: cursor`. Starship lets you change that to whatever you want, but out of the box it hides unnecessary information, and shows you stuff like the your language and package versions, if you're navigated into a git repo, for example. Take a look at it yourself, there's a lot you can do



Does it have async git checks yet?


Based on my experience opening a clone of the nixpkgs repo the other day... I don't think so :)


I love their tagline. Very funny. I used it for a while and liked it enough but their development strategy is explicitly against having configurable options. A few things nagged me and there was no way to change the behavior so I switched to zsh and made it work like fish, but the way I like it instead. For me this was a good decision and I recommend it. (I am not a fan of oh-my-zsh or plugin managers etc either)


can you elaborate on what nagged you? i am just curious, not critical.

i use fish, zsh and now also elvish. the main thing for me is autosuggestion and getting history with uparrow. zsh has a module for autosuggestion. elvish has uparrow history (but only matches at the start). so fish still wins over the others. elvish comes second because typing a command and hitting uparrow once is almost like autosuggestion. but i could not find a way to get that in zsh. i also prefer the way fish and elvish handle blocks over the traditional sh-shell style.


I'm unsure what specific behaviour you want from zsh and the up key, but it provides more than one up-line-*¹² function out of the box. Also, you can add any behaviour you wish with a custom zle function. That said, I understand some people prefer to just use something with the default settings.

¹ https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#...

² https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#...


to explain the up key:

    prompt> some-word[up key]
will search for some-word in the history.

this feature helps because in 90% of cases i can type some-word and have autosuggestion show me the right command, so i just need to hit right arrow and enter to run it. but, if the suggestion is wrong, i can instead hit up arrow and search for a another history entry.

in zsh currently, i can get autosuggestions, but if the suggestions is wrong, i have to type ctrl-A and retype some-word in order to search the history. i want to be able to do that without retyping, the way it is done in fish.

elvish only has the uparrop feature which gets me there halfway, i can type something, and then hit uparrow to find a matching command. in most cases the first hit is the one i want, but if not i keep searching.

i prefer to also have the autosuggestion because often i don't remember that i have a similar command already, and the autosuggestion provides that hint.

together these are the two most useful features that i want from a shell.


That is the difference between the up-line-or-history and up-line-or-search functions that I linked above. The default Up binding is the -history function, whereas the -search function in unbound by default. There are pattern variants too, if you don't like the prefix only checks.

If you also need to mimic the fish behaviour of C-r mid-command because your suggestion wasn't correct, then that does need a custom function to bind to C-r as you have to provide ${L,}BUFFER to populate the search pattern like fish does.


ah, thank you. that actually helps a lot. i don't use zsh as much, but it's good to know that this feature is available. i don't use ctrl-R in fish yet, so i won't miss that.


ooops, typo: ctrl-A above is supposed to be ctrl-R, in case anyone is confused


I don't remember exactly now but I have been on unixlikes forever and I am not too much into fuzzyness in general. I think it was treating upper and lower case characters the same in completions and such. Things of that nature - maybe not exactly that - but when I went to do some research about how to configure it, I realized it was not possible and that was by design. It's very good software that a lot of other shells take inspiration from but I don't agree with their methodology so I took the best bits and made zsh do them, which it can do easily. I didn't use zsh before that and now I am a huge fan.

If anybody who needs this wants to give ZSH a go, I recommend starting with only a few settings and only add new ones if you understand what they do. Same goes for plugins. I do not recommend starting with oh-my-zsh at all - which IMO is a glorified alias database anyway.


The biggest screw up is that fish is not bash compatible. I'm just too used to bash and am not willing to change that because there are corporate systems where I only have access to bash and nothing else; and cannot install fish.

It will just be hurtful to need to keep switching between different scripting languages; I will never be able to do so comfortably and with muscle memory.


I don’t follow… could you put #!/bin/bash at the top of your scripts, and still use it for scripting, but then use fish as your interactive shell?


No, I mean creating some kind of quick program from the prompt itself.

Like for instance bulk renaming of files from the prompt, there is no way I could do that quickly in fish's language and having to switch to bash to do that would be unnecessarily slow. Might as well stick to bash.

What I mean to say is that fish would hurt my productivity rather than boost it.


This is the reason I was amenable to making the jump to zsh.

With the customizations I have in my shell, my bash startup times were creeping into the multi-second territory, but I got a better UX and faster shell startup without having to learn new syntax for simple shell loops.


learning any new tool takes a bit of time. but i believe you are overestimating the effort it takes to learn fish syntax. it is not that hard. you also need to consider the features in fish that boost your productivity that don't need to be learned at all. just give it a try.


I think this is what most fish users do. I suspect that failing to understand this is possible, due to not understanding how shebang scripts are executed by the kernel, is a major reason why bash remains popular for interactive use.


It's not that. We don't want to switch shell syntax between workstation and server, for example. The fish users I've known moved very slowly when they had to hop on a server, or build a new container image where it involved a 'docker run' into the shell to test it out. If you know bash or sh well enough to do those things quickly then there is no incentive to use fish.


> If you know bash or sh well enough to do those things quickly then there is no incentive to use fish.

I honestly think you might misunderstand why a lot of people use fish. I know bash “pretty well”—I’ve written and maintained my fair share of complex bash scripts, and remain pretty comfortable opening a shell in a running docker container or EC2 instance to debug various nonsense. What makes fish attractive to me for use as my login shell is the creature comforts which are very nice to have on my regular workstation, but aren’t really necessary when mucking around in some random environment: syntax highlighting, tab completion/autosuggestion/history search which “just works”, somewhat nicer syntax for writing simple scripts for personal use, saner word splitting, and so on. I guess I can’t really speak for other fish users and am perhaps biased by learned bash first a couple decades ago, but I don’t personally find it especially burdensome to have to remember multiple shell syntaxes/semantics (I already use half a dozen in my day to day work; what’s one more?), and I view it as a reasonable price to pay for a UI I find much more pleasant on whole.


But `docker run` is the same in every shell. The only things that really change is the syntax for looping over files, advanced globing, things like that. Control-R, tab completion etc all works more or less the same with some minor quirky differences, but nothing that would slow somebody down.

Context: I used bash for about 5 years, zsh for the next 10 before switching to fish.


i use fish for interactive work and bash for scripting. if there is a script that i don't want to write in bash, then i use a real programming language like python or ruby.


as long as you're not doing conditionals and loops you probably won't be able to tell you're not using bash

personally I almost never put anything that complicated into my shell, once it gets to that point it goes into a script.


I haven’t found much need to swap due to using bass

https://github.com/edc/bass


That's not a screwup, that's the point of fish.

You can't make a sane shell scripting language without dropping POSIX compatibility.


I don't believe that's the goal they set out for themselves; and besides I feel like it should at least be as POSIX compatible as they could make it. They could drop POSIX oddities where they see fit, but POSIX is not all insane.

I mean, I really doubt that the `export` command is terrible somehow. In fish, you have to use `set -Ux` which is just ridiculous and petty of them, the world doesn't revolve around the fish developers and this just breaks many files that you try to source from fish; for example, Python venv activation scripts.

As for why I don't think that's their goal, just look at https://fishshell.com/ not one of the listed features requires them to drop POSIX compatibility entirely. I just want something like fish shell that isn't too radical and tries to be as POSIX compatible as possible while adding their improvements, out of the box (so ZSH doesn't count).


> As for why I don't think that's their goal, just look at https://fishshell.com/ not one of the listed features requires them to drop POSIX compatibility entirely.

“Sensible scripting” is right there.


I don't use fish but it does have one great feature that I'm surprised hasn't been replicated in zsh: automatic completions derived from man pages. So you get at least basic flag completions for basically every program automatically.


Nushell > Fish > ZSH > Bash

I tried a lot of shells and that's what I ended up with.


I used fish for a while (and really enjoyed it, it's a great shell), but it's formatting is too inconsistent with bash for me. I found myself dropping back to zsh so often to write documentation or run a playbook that I switched back.

If you often share shell code with others it may be to big of a leap for you.


I use fish since they relented and allowed to use && and || instead of ;or and ;and. Still, I always script with bash (or POSIX sh for certain things). I can't recommend that split enough. Also, I can't speak highly enough of shellcheck[1], it's a lifesaver especially when you target POSIX.

1: https://www.shellcheck.net/


I'm there with you on that.


If you're running a script, you can use edc/bass to run it from a fish shell. Fisher is one of the first things I install after fish, then bass, z and a few other helper plugins.

https://github.com/edc/bass

https://github.com/jorgebucaran/fisher


I was hesitant to switch to fish shell, but after seeing so many recommendations on HN, I gave it a shot. Been using it for a while now, and it's mostly good.

The one hiccup is the syntax; it's different from ZSH, so you have to update your existing config. ChatGPT has been pretty useful for that, though.


At least now && works. It used to not be the case and required you to type ";and" which was incredibly annoying as you had to modify basically every single command that you found online or that people sent you.

Now that && works, I don't have any big conplaints about it anymore.


I don't know much about shells. Fish was the first one that made everything so easy and the only downside was not being posix compliant, but i can easily call bash and run the command. I tried leaving fish and the others requires so many configurations, but fish does by default. It suits me.


I may be mistaken, but since I have to work with different machines that all have bash as a shell, I try not to mess with my muscle memory and stick to bash even on my own machine. But maybe I should try Fish.


Been using it for years. Accidentally found out a few months ago, shift+tab allows you to search for completions.


I like fish. It's good to have on my machine. I can see myself using sometimes. I'm used to bash. Bash for scripting definitely. I'm not sure what makes me look more like a "hacker" using bash, or using fish?

I don't really care, but...ha! Just wondering.

I guess fish is like, you feel like you're living in the future, but also like "this is a past that should have already been available" then you find out it has been available, for 18 years, and you wonder, "Was it me that was living in the past?"

It's the kind of thing I'm scared to get burnt on, when it fails, because I already like it. I don't want it to disappoint me, because I just feel like: "new fangled, it's always gonna break." But then, it has been around for 18 years...so...hmm.

So, I don't know. It looks pretty! I like to use it. But bash is, feels, more stable.

Worth exploring! I'm not gonna config-it, as much as possible, but for interactive shell? I think it's good! :)


Fish is a pleasure to use, been using it for about half a decade.


Fish is pretty good, but I wish it would come with fzf-like capabilities built into it by default, for automatically searching history/files/etc.

Yes I know I can just install fzf and the fzf/fish integrations, I've done so. But my understanding is that the whole point of fish is that it comes well configured by default. fzf is a quantum leap forward for shell UX, this sort of functionality should be built in by default.


I quit fish because I missed being able to `sudo !!` to rerun the previous command with sudo. There's an alternative way to do it (something like up arrow, ctrl-i, "sudo", enter), but I can never remember it when I need it, which is not often enough to stay in my head, but often enough to be come quite annoying.


I hope that you are joking since you just have to press `Alt` + `S` to rerun the previous command with sudo in fish-shell:

> `Alt` + `S` Prepends sudo to the current commandline. If the commandline is empty, prepend sudo to the last commandline.

https://fishshell.com/docs/current/interactive.html#shared-b...


Glad to hear that's changed. There were strident statements from the developer on Github last time I researched it to the effect that implementing '!'-style history expansion was contrary to the fish philosophy and that people just need to learn the fish-y way. Looking back it, I probably could have fixed the issue for myself by setting up vi-mode in fish, but I didn't come across that option at the time.


That is a recent(-ish) addition¹, arriving in 3.1. Your interpretation of recent may be a different length to mine, but one Debian release in this instance ;)

¹ https://github.com/fish-shell/fish-shell/pull/6140


I guess he wasn't aware. I use fish, and I'm learning this now too. I probably really should give the fish docs a read-through, as I imagine it could significantly improve my shell efficiency.


You can set this up to work the same way with the recent abbr changes, and I believe they may add it as a default in the future.

  function last_history_item; echo $history[1]; end
  abbr -a !! --position anywhere --function last_history_item
source: https://fishshell.com/docs/current/relnotes.html#id1


I also bounced off of fish for the same reason.

This post has prompted me to give fish another go, so I looked into it again.

It looks like the abbreviation system can now (since March this year) help you with !! (https://fishshell.com/docs/current/cmds/abbr.html even gives it as an example)

I also use `!$` (`vim script.py` and then `python !$` or `git commit !$`) but the parser rejects `!$` before it can be rewritten by the abbreviation system. [edit: https://superuser.com/a/1762626 points out that if you add a space before hitting enter then it works fine, so I'm guessing it's just a bug, and I should go with d below]

Options seem to include:

a) make a !$ replacement that is not illegal and change your muscle memory `\$` or `!\$` or `!@` or `!%`

b) use a keybinding for !$ as suggested in https://github.com/fish-shell/fish-shell/issues/288

c) some combination of a and b (e.g. make a `!\$` abbreviation and then make a binding so that if you type !$ it replaces it with `!\$` so that it gets past the parser without expliding)

d) patch the parser to allow !$ as a special case if there is an abbr for it.

I just tried b but it's pretty jarring. I think I might go with c instead.

I'm actually feeling quite positive about this now.

There is something I've been wanting to add to bash since forever, which is something to help me cd into a repo that I just cloned (e.g. `git clone https://github.com/fish-shell/fish-shell` then `cd !/` could expand to `cd fish-shell`).

Exciting times.


Bash has a range of modifiers for history expansion. You can "cd !$:t" to execute "cd <final argument of last command, basename only>" for your git example. zsh, somewhat predictably, has a superset of bash's modifiers so it works there too.


That behavior was added earlier this year - https://fishshell.com/docs/current/relnotes.html#fish-3-6-0-...


Not to hijack, but also consider xonsh[1]. It's Python based, and all your scripts can be Python (or hybrid-Python). I've been using it for both Windows and Linux for over 5 years.

[1] https://xon.sh/


I'm interested especially for Windows, does it have any of the footguns relating to awful corporate network drive setups, $HOME, expensive prompts, and the like?

I need a good shell for when I'm forced to work on Windows machines (and when WSL isn't available). Git Bash (and even plain MSYS2 bash) performance is so unbelievably awful every single time, and the fixes can be hard to determine and a giant pain in the ass, and sometimes impossible if they are due to windows defender or whatever antivirus junk the corporate environment has installed.

However, Python runs fine, so maybe Xonsh would run fine?

I realize I should probably just use PowerShell but I strongly dislike the syntax and would have to write function wrappers for basically every command I setup. I'm sure most here can relate to that.


> does it have any of the footguns relating to awful corporate network drive setups, $HOME, expensive prompts, and the like?

Not sure what you mean - can you give an example?

There will be a $HOME environment variable.

I never use WSL, Git Bash or Cygwin stuff. Just the normal command prompt with xonsh running on top of it. So I can't speak to performance issues. If you could give examples, I may be able to address them.

Definitely should not have issues due to antivirus. It will be a program running continuously.

> I realize I should probably just use PowerShell

Powershell is probably the best, but I didn't want to expend energy learning it. With xonsh I can have the same config in Linux and Windows, and Python is always a plus.


Tried fish a couple of times, it's really good, many zsh plugins are created to replicate features of fish. But it's not my default shell, because I need to run bash shell scripts and I didn't find any way to do it in fish. So I am stuck with my slow zsh.


I often see people complain about this but I seriously don't understand. The shebang at the top of a bash script will point to bash no matter what your shell is.


At various jobs I've often seen bash scripts to set up your environment (mostly environment variables). Running a bash script with shebang will not preserve the changes to the environment variables, will it? At least that was my experience.

I use xonsh and fortunately it has source-bash for stuff like that.


I've never needed it, but there is bass for this use-case: https://github.com/edc/bass


Yeah I would have thought so too, but I have personally ran into this issue running fish-shell on my mac. There are some scripts I need to run that do not work even when I shebang the script to run in bash.


That's really odd. I have never had a single issue with this, I don't understand how shebanged scripts can fail? What's the error?


Yes, it really is odd, I couldn't figure it out so switched back to zsh.

The specific issue was to do with a script we had to run to gain ssh access to an internal network. I can't post the script, but it was related to openssh.

Even logging into bash and running the script didn't work, I had to remove all fish binaries, symlinks, etc and set my shell to bash/zsh. Maybe it was an issue with how I installed fish, but yeah like I said, very strange, but I can vouch that I've encountered a similar issue before

It's a real shame because I think the fish syntax alone is worth the switch, for my personal machine(s) I use it.

Edit: this was years ago now, about 4 years, maybe the issue doesn't exist anymore but it caused me a bit of grief at the time (beacuse I didn't know it was related to using fish!), I've not since tried it again. I might try again and get back to this thread


> I had to [...] and set my shell to bash/zsh

Most likely a command in your script (or one source-d into it) makes an assumption about your $SHELL or login shell that is true for bash/zsh but not for fish.

Merely adding a shebang won't fix such a script.


See my other comment and let me know if that script contains

  ssh-agent $SHELL ...
or

  exec $SHELL ...
or

  eval "$SHELL ..."
or similar. :)

If it ends up passing a script file or arguments to $SHELL and you wanna fix it without rewriting it, just add some conditionals where $SHELL is used and use the equivalent flags or syntax when $SHELL indicates fish.

Alternatively, if you just wanna work around it, just launch that script like

  env SHELL=(which zsh) whatever-script.sh


fish doesn't have builtins but all fish commands are external binaries or fish functions. i think at one point early in the history of fish those binaries may have been installed on the global path so they were accessible outside of fish and possibly there was a name conflict with one of them that this script triggered.

although such a name conflict should not have happened (and i can't think of which command such a script might have used that would also be a fish command), and the global path thing was also fixed soonish. but this is all a faint memory, so i am not sure i remember any of that right.


Fish definitely has builtins, for example

  - cd
  - source, .
  - eval
  - string
  - and
  - or
  - builtin
  - command
and many others.

Not sure what the point of distinguishing between fish builtins and fish functions is; whether a builtin is shipped as a function distributed with fish or a reserved word in the fish evaluator seems like an implementation detail.


fish has grown and evolved. i was referring to this:

Builtin commands should only be created when it cannot be avoided. echo, kill, printf and time are among the commands that fish does not implement internally since they can be provided as external commands. Several other commands that are commonly implemented as builtins and can not be implemented as external commands, including type, vared, pushd and popd are implemented as shellscript functions in fish.

if i remember correctly, this led to some useful commands that are builtin elsewhere to be external binaries shipped with fish. but since those where not actually tied to the fish shell they could run without it, and if they ended up on the global path be accessible from other shells.

the relevant text on the website has been changed, but it is referenced here:

https://github.com/fish-shell/fish-shell/issues/612

the discussion also points out that this has changed over time


Idk if fish has ever shipped builtins that way, but doing so is pretty conventional and doesn't normally put those executables on the PATH. It's what libexec is for: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.htm...

If you wanna add a builtin like that to your own distribution of fish, you could do it cleanly by keeping those binaries in /usr/lib or /usr/libexec and then wrapping them in a fish function that ships in fish's install prefix. (This is basically how fish's Python scripts for generating completions from manpages are shipped today.)


doesn't normally put those executables on the PATH

right, i don't remember the details, but when it happened it was probably fixed quickly. could even have been a packaging error in a distribution.


the shebang is literally handled by the kernel, so fish has nothing to do with this here.

are you sure you're running `./scriptname` or bash scriptname`


This is plausible if you have scripts that do dumb shit like

  eval "$SHELL ..."
because (at least sometimes?) $SHELL is set by your login program and not your shell, and dropping to an alternative shell by just typing

  zsh
and hitting enter or whatever won't reset $SHELL.

You mention elsewhere that this had to do with a special OpenSSH setup, which also fits.

One of the things you can do with ssh-agent is use it to launch a child process with a dedicated SSH agent that (only) has certain keys on it, and which exits once its child exits. This is sometimes handy for deployment scripts or doing git checkouts or whatever because you can ensure you don't get locked out for too many auth attempts because the user just has too many extraneous keys on the agent associated with their normal user session.

If you were leveraging this feature for interactive shells, you might be tempted to use $SHELL to decide what executable to have ssh-agent launch, so that you could (for example) accommodate both bash and zsh users and let them launch a shell with a special SSH agent but which honors their usual preferences by loading their usual shell and reading their usual zshenv or bashrc or whatever it is.

You mention as well that you had to actually uninstall fish to get things to work again, and also that you were on macOS. I can't be certain about the cause here, but one obvious thing occurs to me:

macOS doesn't handle environment setup like any 'normal' (Linux or *BSD) Unix. On normal Unices, your login shell actually also launches your graphical user session, so to configure a session-wide environment variable, you just set it in your shell startup somewhere. On macOS, login shells are actually only used in SSH sessions and terminal emulators. If you want to set environment variables for apps that are not launched from terminal emulators, you have to use hacks (like Doom Emacs' env file, for example) or configure them for the whole user session via a LaunchAgent.

In the case of $SHELL, that environment variable is used by editors to determine what shell to use when you run external commands. Without it, if you are a fish user and you launch MacVim or Emacs (or, presumably, VSCode or anything else) from your dock, when you go to launch external commands, they will run not in fish but some other shell (probably zsh or bash). If your install method for fish tried to handle this for you (pkgsrc and Nix don't, but the .pkg from the developers or Homebrew might, idk), or if you dropped to bash only from terminal emulator windows that were already running fish instead of opening a new session for bash, you may have wound up in a bash session where $SHELL was still set to fish. That's the only reason I can think of for why you might have had to actually uninstall fish to get this ill-behaved script to work right.

Anyway:

1. As a user, pay attention to what $SHELL is.

2. As a script author, never use `eval "$SHELL ..." or equivalent`.


> macOS doesn't handle environment setup like any 'normal' (Linux or *BSD) Unix. On normal Unices, your login shell actually also launches your graphical user session, so to configure a session-wide environment variable, you just set it in your shell startup somewhere.

That's no longer true for Linux, at least. GDM launches stuff via systemd user sessions, which do not source your profile.


Huh. Not a GNOME user so TIL.

I'm not sure how I feel about it. The old way feels 'simple' to me, but the new way does mean that shell misconfiguration won't hose your GUI sessions.


Is the path you’re shebanging to correct? One of my coworkers was having this problem and it turned out his path had a typo in it.


this sounds really strange. i don’t suppose you have an example?


You don't have to translate them. Just stick `#!/usr/bin/env bash` on top. It is totally fine to use fish as your "terminal shell" and default to Bash for scripting for things like automation, etc. I've been doing this for a decade. I will also add that Fish is so good by default that I barely have any config.


Is the issue running bash shell scripts or copy-pasting one liners? If the latter, you can always use the command flag for bash to execute one liners within its own context.

    bash -c "grep word file.txt | sort -u | tail"
Scripts shouldn't be an issue as long as you either launch it with the proper shell or configure the shebang correctly after making the script executable.


What do you mean? If the script is using hashbang, you can just run it. If not, run "bash script.sh". If you need to source it, use the plugin "bass". If you want to run a one-time bash command copypasted from somewhere, just type "bash", run your command, and then ctrl-c.


I just run `bash script.sh`, or `./script.sh`? What does not work for you exactly?


Maybe ask ChatGPT4 to translate them?


I asked an LLM to translate a bash script to fish once and it just changed the shebang line... cracked me up.

Edited to add:

There's a program out there for translating bash to fish called babelfish. It's pretty good but not complete, so it won't work for all scripts. Worth checking out, though:

https://github.com/bouk/babelfish


Yeah, I've seen those stuck in loops where they don't see an obvious mistake.


this shouldn’t be necessary and is probably fairly error prone. using one shell doesn’t mean you can run stuff in another.

if someone is saying they can’t run a bash script when they’re invoking bash from fish the most likely thing is they’re doing something wrong.


If you use Fish shell and Python, my project VirtualFish can make managing virtual environments a lot easier and more fun:

https://github.com/justinmayer/virtualfish


Thanks for mentioning. I think it would help a bit if you copy-paste a short terminal session to show what VF looks like in operation. I know there are extensive docs, but a quick tldr/screenshot helps quite a bit in a README I find


Hi. I'm Ilya Sher, author of Next Generation Shell. That's the only shell that I'm aware of that plans to do something "radical" about the UI/UX. By radical I mean something out of the telegraph style communication paradigm.

https://ilya-sher.org/2022/12/31/telegraph-and-the-unix-shel...

https://blog.ngs-lang.org/2023/06/08/the-shell-vs-the-web/


I loved fish for about 5 years. My only gripe is that going back to Mac it wouldn’t play nice with the terminal color scheme, or the dark mode switch. Anyone found a way around that?


I use iTerm2 instead of the default Terminal app. In iTerm2, you can change the impossible-to-see blue and red to more reasonable values (or do what I do and use the Dracula Pro Themes).


Fish has some options for that via `fish_config`: https://fishshell.com/docs/current/cmds/fish_config.html. You can use the browser tool or `fish_config theme ...` to find colors that work better.


I had to abandon the last time I tried fish because it’s not compatible with my export PATH declarations from tooling in bash/zsh, any tips?


OK so if you're new to fish you should understand universal variables since it's a concept that bash/zsh does not have and it's actually pretty great.

When people first try out fish they want to add their global env vars and PATH configuration to ~/.config/fish/config.fish. You can absolutely do this similar to how you do it in ~/.bashrc. However, it's not idiomatic and once you get used to universal variables, you'll see that it's a lot of yak shaving you really just don't need editing config.fish.

Instead, if you want to permanently set an env var across the current session and all new sessions, run: `set -Ux MY_ENV_VAR 1` (set a universal variable, and export it to subprocesses)

That will put it into a machine-readable file ~/.config/fish/fish_variables. You can open it if you want but this way you don't need to source your rc files, open a new shell, or even open your editor.

For PATH, just run: `fish_add_path ~/my-new-bin`. It uses universal variables by default.

For some reason I avoided universal variables as much as possible for years using fish and now I think that was really silly.


Just rewrite them once with fish_add_path? https://fishshell.com/docs/current/tutorial.html#path Or maybe use https://github.com/edc/bass


I think later versions of Fish do support export statements. This line of code works with Fish, as well as Bash and Zsh:

  export PATH="$PATH:$HOME/foobar/"


You can source bash files (like .bashrc) using the plugin "bass". You can also launch fish using a bash file, just export the variables and run fish as the last command.

I personally just put what path modifications I need in .profile and have fish as my login shell.


Why use this over nushell?


They're really completely different. Fish is mostly about having features that help you enter a command (history, error checking, completions, etc). Once you execute something, it really behaves the same as bash/zsh.

Nushell is really more about command output (my understanding, I haven't used it heavily). With Nushell you can do things like parse TOML files right in your shell:

    open Cargo.toml | get package.version
Nushell understands the structure of data but fish is like bash/zsh in that it just deals with streams of text. Nushell can even interact directly with sqlite databases which is very cool.

I think if you're just looking for a simple shell that behaves a lot like bash/zsh, use fish. I think Nushell is more targeted to people that want to use its powerful data pipeline features—or are generally interested in a bigger departure from bash/zsh.

Personally I prefer fish, but I should start using Nushell more since it could definitely help with some tasks. I probably would just run Nushell when I need it though, I don't see myself running chsh to switch over.


i can't find anything about history handling in nushell. it's one of the key features of fish


They recently added sqlite backed history. You can also use atuin[1] for more advanced usecases.

[1]: https://github.com/atuinsh/atuin


I’ve used fish for nearly a decade now, it’s awesome. The autocomplete works for so many things you don’t expect!

Command line arguments! Remote path completion! Git!

It’s something I install basically on everything machine I can. The history based autocomplete is so useful for keeping track of and refinding those less used complex commands that you have not saved in a function yet.


I think it's not Bash compatible, had issues in the past to run some programs and scripts


Am i the only one who feels fish is not worth it despite of hype? Don't get me wrong. I think that fish is really good shell.

BUT...

After adding the following plugins to zsh(before you chime in, it's just adding these lines,not anything configuring much. also it auto bootstraps on new install), I found out that fish is no where as good as configured zsh.

1) https://github.com/zdharma-continuum/zinit (plugin manager)

2) https://github.com/zdharma-continuum/fast-syntax-highlightin...

3) https://github.com/zdharma-continuum/history-search-multi-wo...

4) https://github.com/zsh-users/zsh-autosuggestions

5) https://github.com/zsh-users/zsh-completions

6) https://github.com/Aloxaf/fzf-tab

7) any good shell prompt generator like https://github.com/romkatv/powerlevel10k

For example, I use fzf integration for tab completion. Fish's fzf integration is nowhere as good as that of zsh's. Also, posix compat and almost bash compat of zsh is plus.

I acknowledge that zsh isn't perfect shell either and I have tried and failed few times in past to switch to fish. If you provide me compelling reason/s to switch to fish, I am all ears.


Sincerely: What hype? heheh –I see fish as a mostly obscure shell with some design principles.

It works for me. It’s a great tool.

I tried zsh; zsh was a lot slower as I set it up. Maybe I did it wrong.

I think the case is that with either of fish or zsh you can’t lose. Both are great.


well, one of the big benefits is that i don't have to set up all this in order to get the functionality, because fish provides it out of the box.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: