212 comments

[ 2.9 ms ] story [ 246 ms ] thread
I love fish shell, I love the autocomplete, but I've been forced to switch back to bash lately, because fish syntax is just different enough from bash-isms to break too much scripts / tools / commands.

I know I could just invoke bash, but prefixing commands with "bash -c '" is tiring and papercuts are why I switched to fish in the first place. I wish bash had a sane auto-complete prediction like fish.

Fish doesn’t break scripts, they use whatever interpreter you specified when you wrote them.

I use fish interactively and write very simple scripts in bash and the more complex in Python.

Maybe op is sourcing said scripts instead of executing them?
(comment deleted)
Your scripts should begin with #!/bin/bash or similar so you can execute them from anywhere. Are there bash built-in commands or functions that you need while in fish?
There's some initial pain in retrofitting your Bash startup to work under fish, but after that it's worth it. For example I had to search for how to use ssh-agent with fish, and now it works great: https://github.com/st3fan/dotfiles/blob/master/fish/ssh.fish

You need to learn a few idioms like: replace $[1+1] with (math "1+1"); replace

> for f in $(ls); do echo $f; done

with

> for f in (ls); echo $f; end

I should start a Rosetta Stone of Bashisms to Fishisms - I'd be interested if anyone has got Android Open Source build environment / lunch working.

bash uses readline to handle user input and in readline the completion function is a parameter. Could a more clever completion function be substituted to get the same behaviour with bash?
You can get it much of the way there by tweaking `~/.inputrc`

"\e[A": history-search-backward # Up key

"\e[B": history-search-forward # Down key.

Allows you to get press up while you have `ssh 10.2` in the terminal to cycle through ips matching, etc. It won't display like in fish before pressing it, but I find that's a reasonable tradeoff.

(comment deleted)
FWIW I'm working on a bash-compatible shell:

http://www.oilshell.org/blog/

If nothing else, I have thousands of lines of my own shell scripts that I don't care to move to a different shell syntax that's not obviously better :)

There are lots of posts on the blog about it, but here is an example:

"OSH Runs Real Shell Programs" - http://www.oilshell.org/blog/2017/07/02.html

Another comment: https://news.ycombinator.com/item?id=15916470

However one thing is that it's not yet a good interactive shell. It's mainly treating bash as a programming language. However I think that is a good foundation for an interactive shell. Some details here:

https://www.reddit.com/r/commandline/comments/7c3f9f/osh_02_...

Fish is really great for using it in your terminal. Autocompletion, fuzzy matching, and so on, are amazing.

Unfortunately, although it is fully scriptable, writing scripts in Fish feels a little clunky at times. For example, I wanted to test if $dest exists, and if not, whether $src is newer than $dest. Since there are no && or ||, parentheses are used for command substitution, and the Fish version of "test" has no -nt to check if a file is newer, I have to do this:

    if begin; not command test -f $dest; end; or begin; command test $src -nt $dest; end
        # do something
    end
Yeah, wow... I would have to spend at least 15 minutes figuring out what that does.
I'm a very happy fish user but this is one of my pain points as well. If you want to define a function, the syntax is light-years ahead of bash, including named arguments (and closures!), but it took a fair bit of googling and eyebrow-wrinkling before I could figure out the way just to set a default argument for that function.

What I ended up with was (for a shortcut for generating a password on the command line):

    function pw --argument length
        test -z $length; and set length 16
        python3.6 -c "import secrets; print(secrets.token_urlsafe($length))"
    end
When I last needed something similar, I wrote it like

    not command test -f $dest
    if or command test $src -nt $dest
        # do something
    end
It saves on the begin ... end, but is confusing to look at. Nested conditions are really not very ergonomic in fish.
It's true fish is generally more verbose, as it has less magical syntax. fish is also missing some niceties like `set -e` and `set -x` which we would like to add, but the main focus is interactive use.

Happily the begin/ends in ifs are no longer necessary:

   if not command test -f $dest
      or command test $src -nt $dest
     # stuff
   end
In this particular case, you can simplify it further with test's operators:

    if command [ ! -f $dest -o $src -nt $dest ]
       #stuff
    end
which is comparable in length to bash, though other cases will certainly be longer.
use ; in place of &&
I think you should actually use "; and" in place of &&. That said I still wish fish support && and ||, if only for the times when I copy and paste some one-liner off of stack overflow and have to rewrite it.
I’ve been enjoying fish for the handy tab complete of command line options, the interactive history, and it’s pretty.

I’m certainly guilty of finding one-liners online which frequently fail in fish, which puts me in the position of either actually learning what the terse statement actually does and re-implementing it in the fish “c-like” syntax, or I just drop into bash then get on with my business.

Really happy with it, but I know I get sideways stares from graybeards and gurus who consider it the small-batch, fixed-gear, “Crocs” of shells.

Happy user here. If you spend a lot of time in the shell fish is totally worth checking out.

Good points:

* Fish's completion sure saves a lot of typing

* `brew install fish` on osx

* Config in ~/.config/ rather than cluttering up the root of your homedir

* Can change many settings without needing to edit config directly - eg. `set -U fish_user_paths $fish_user_paths ~/path/name`

Bad / not intended for:

* It's not for scripting. Just use bash for that.

* I've found appending to env vars to be fiddly. Maybe I'm doing it wrong

* pyvenv's bin/activate.fish was broken for a long time (not fish's fault!)

Just curious, since their website pretty clearly points out "sane scripting" as a high point, what makes it bad for scripting from your perspective?
Bash scripts are way more portable. But for little scripts that only I will run on my computer, Fish is great.
Bash scripts are also much more brittle. I don't do bash scripting at all anymore. I fish for personal/usage or perl/python for shared scripts.
Correction: Most bash scripts are brittle. You can write rock-solid bash scripts if you know what you're doing. For example, Arch Linux is an entire distribution built mostly on bash scripts.

Of course, if your scripts only run on your own machine (which is a huge if), then fish is probably better.

Sure you probably can write non-brittle bash script, but it has always seemed above my own ability. Beyond bash ubiquity, I've never found to have any other value against other slightly higher language whether it is perl, tcl, python, etc ...
shellcheck helps a bit
Not GP, but since 90% of of my sporadic scripting is "searching on SO how to do something somewhat complicated that I'll never do again so it's not worth the time to learn how to master it", bash is (oddly enough) a lot easier to use here since looking up how to do it in Fish is a lot more hassle.

Similarly, if you want your code to be portable, bash is a safer bet.

I put that badly. Fish certainly does support scripting, but as a relatively niche piece of software you get bad portability (everything has bash) and poor maintainability (because everyone else scripts in bash). Fish is a great shell and maybe this will change, but at the present time I'd be doing my clients a disservice if I wrote them tools in a language few others could work with.
I find fish to be a more pleasant scripting languge personally, but bash scripts are the lingua franca everywhere I've worked. It's easier just to learn bash.
I wouldn't use it because I wouldn't want to add a somewhat strange and unnecessary dependency to my projects. It's also why I resist switching from bash even though I've used other shells and enjoyed them. There are only so many skills I can keep in good practice. If I use bash then it will be one of them.
1) web based configuration? really?

2) list.reverse(macOS, Linux, and the rest of the family)

That is the one thing I really didn't like about Fish; that and how the help screens use to launch in a web browser. But once you get past the initial configuration, you never use that stuff again. Despite that fault, I still love Fish shell.
`help` opens in the browser, but fish also has excellent man pages for all of its commands.
As much as I hate HTML documentation, at least it's not info.
The web based configuration is completely optional. Editing dotfiles works just as well. I have been using fish for quite a while but never use the web interface (I didn't even remember it existed)
I've been using fish for 3 ~ 4 years and I love it. It's come a long was in its development and it's interesting to watch as so many of the bugs have been resolved. Today's fish is incredibly stable and solid. The history, highlighting and completion are well beyond what I've seen in other shells (at least not without adding additional plugins).

I still write scripts in bash for compatibility (when I have to; I try to use Python whenever it's an option), but for my interactive shell, fish is really amazing and I'd hate to go back to anything else.

I've been using fish for a few years now, and it has made bash feel not just outdated, but completely obsolete. I am at loss for why it hasn't taken the entire world by storm.
Fish is nice and I eventually learned to accept the scripting. BUT if it is the shell for the ‘90s what is the 21st century shell?
It's a joke. The implication is that Bash was already outdated in the 90s, so it's long past time for something new.
I know, just trying to be too pithy :) But will seriously look at some of the other shells mentioned. I miss scsh.
Fish with a plugin for ironic comprehension.
Gah, probably node...
TermKit possibly fits this: https://acko.net/blog/on-termkit/

I'm not so sold on some of the tokenizing / etc styling, but `cat image.jpg` -> see an image? yes please.

Alternatively, I keep checking in on Xiki periodically, since it has some extremely interesting features: http://xiki.org/

iTerm has an imgcat command, which is occasionally handy (works independent of your shell)
I made a comprehensive list of shells here:

https://github.com/oilshell/oil/wiki/ExternalResources

Of course I think my own project, Oil, could be a "21st century shell", or I wouldn't be working on it :) It's designed in a principled way, and it's also the only one that's compatible with bash.

I've never tried it and spent the last few years relying on oh-my-zsh, is it worth trying to switch?
I used fish twice for about a year each time, but I keep switching back to zsh, because:

* The main things I like about fish are predictive history completion and syntax highlighting, both of which work about the same with a pair of zsh plugins;

* The syntax occupies what is, for me, an awkward middle ground: it's a bit better than POSIX syntax if POSIX shells didn't exist, but not enough better that I care to juggle the two syntaxes;

* I don't like that fish tries to be "helpful" in certain cases such as lying to you about the delimeter actually used by $PATH.

I have a couple of specific gripes about the syntax, which aren't really inherent issues so much as unimplemented features.

I think if I was going to deviate from a POSIX shell, the alternative would have to be more better than fish to be worth it.

Out of curiosity, what use case do you have that makes a POSIX shell a big deal?

I’ve never had issues as a somewhat heavy user.

It's nice to be able to simply copy-paste commands from the internet sometimes. (obligatory: yes you have to be careful when you do.)
There's nothing major. I maintain a set of POSIX and fish scripts as part of my job and, given that I have to know both relatively well, I find I end up preferring the on-average-slightly-more-terse POSIX syntax.

One thing that can be particularly annoying is that it seems to be impossible in fish to evaluate a command in a subshell and embed its output into a string without assigning it to a variable first.

ARGV handling is a little weird too. I understand the impulse to get rid of $1, $2, $3, $*, $@, $#, etc., but it ends up just requiring different gymnastics, like writing `set -e argv[1]` instead of `shift.

> Out of curiosity, what use case do you have that makes a POSIX shell a big deal?

Running on a POSIX system, there are decades' worth of shell snippets out there which don't work with fish, but do with sh, ksh, bash & zsh.

Fish is just gratuitously incompatible. Having fish-users on a team is a pain, because they'll write everything in fish and either not bother producing sh equivalents, or produce insufficiently-tested sh equivalents. It's just a lot of pain and bother, and what's the benefit? Zsh does everything fish does and more, so why not just use it?

Edit: I just wish that the original fish developers had chosen to implement all their cool features and be sh-compatible, or at the very least had exercised some wisdom in where they chose to break compatibility. Instead, it very much feels like a 22-year-old's project: full of ideas, some good & some bad, and needlessly without respect for the past. I've no problem with rejecting the past when the past is broken (and sh is broken in places); my problem is with the equivalent of saying, 'hey, English spelling is terrible, soh Aiv dəseidid tū dəvelup mai ohn.'

Back in the day I used to use csh and tcsh, both of which had famously landmine-laden scripting gotchas. So, I wrote my scripts in sh or bash. Now that I use zsh mostly, same thing, I don't actually write my scripts in zsh--especially for production, I write them in sh or bash. zsh for me is an interactive CLI-only tool. Honestly, I think the problem here sounds more about not standardizing on a common denominator for shared scripts.

Where stuff like fish is a pain for me is with apps that for whatever reason need shell integration (virtualenv, for example). Non-POSIX shells end up being an afterthought there, so you end up with no or buggy support, and end up having to find some other custom variant (virtualfish, etc.) to get good behavior. Sticking with a more mainstream shell tends to be safer there, and zsh barely makes it over that line.

What are the ZSH plugins that you use, out of curiosity?
I started with bash, moved on to zsh and finally settled on fish. Besides fish being super user-friendly out of the box, I couldn’t find a zsh plugin that emulated its history search abilities.
I use the following lines in my .bashrc to search the history based on a half-typed command (taken from https://stackoverflow.com/questions/1030182/how-do-i-change-...):

    if [[ $- == *i* ]]
    then
        bind '"\e[A": history-search-backward'
        bind '"\e[B": history-search-forward'
    fi
There are two history search features in fish that I really like: One is searching for a half typed command as above, but the other one that I haven’t found elsewhere is completing words from other commands. For example, I can type ‘touch something’ and later on do ‘cat some’ and then press option+up and fish will complete it to ‘something’.
After using ZSH I have that first feature and love it. I try to keep as much of my history as possible and it's amazing how much time you can save that way. Does that second feature not clutter up that history though?
Is it possible to configure zsh to have sane variable expansion like fish does? One of my favourite parts of fish is that I don't need to quote every variable I use out of a paranoid fear that they might contain spaces.
> * The syntax occupies what is, for me, an awkward middle ground: it's a bit better than POSIX syntax if POSIX shells didn't exist, but not enough better that I care to juggle the two syntaxes;

This. It's an awesome shell, but I couldn't set is as a default because my already done shellscripts and aliases would stop working. And I also can't set it on server, because then a deployment tool logs in, and expects bash.

And if it isn't default, I might not bother, I'd forget to run it manually most of the time.

(The worst offender is replacing && with 'and' - why not at least enable both and preserve compatibility?)

It is also worth noting that the ecosystem around fish is quite developed, making it easy to get easy integration and completions for most well-known tools.

oh-my-fish [1] plugins is a good place to see (part of) what is available

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

Hey all, one of the fish devs here. It's awesome to see all of the comments and happy users.

We are in the process of scoping a major release (fish 3.0) that can include major syntactic changes. If there's an aspect of fish you would like to see changed, now is a great time! Of course we'll read the comments here, and our issues page [1] is where discussion happens.

We're also welcoming new contributors. It's easy to get started writing completions or with the issues labelled "easy-pick". The core code base is reasonably modern C++ too.

http://github.com/fish-shell/fish-shell/issues/

(comment deleted)
I see that https://github.com/fish-shell/fish-shell/issues/3341 is scheduled for 3.0. This is also marked as the fix for the broken/invalid YAML format that is used for storing the shell history https://github.com/fish-shell/fish-shell/issues/2258

I implore you to NOT use JSON or ProtocolBuffers, neither are appropriate formats for configuring my shell, or storing long sets of textual data. Protocol Buffers is hardly the kind of format I want to parse and read my history in, and JSON is a less than ideal configuration format for many reasons.

https://github.com/vstakhov/libucl UCL (Universal Configuration Language) is a much more appropriate format for configuring programs than JSON, and is has been accepted as standard for use configuring all tools included in the FreeBSD operating system.

I also suggest you consider using a different language to store shell history, since shell history and shell configuration are two very different jobs with different goals and trade offs. I personally would suggest a simple safe format like TOML https://github.com/toml-lang/toml for storing the history.

But If you do want a single format for both configuration and history, I would implore you to pick TOML not JSON or Protocol Buffers.

Thanks for writing that up, I linked to it from the issue. FWIW I agree with you that shell history should be a simple format, and even ad-hoc parseable via Unix tools. zsh uses simple : and ; delimiters. JSON is more complex, and binary formats like protobuf are way out.
Out of the mainstream formats, JSON is among the easiest to parse - thanks to the CLI tool jq. Does UCL have something equivalent?

Protobuf (or any other binary format) has the benefit of being faster to load, but I agree - it should not be be used to store things like history. It should be easy to parse history without having to write code. And with Protobuf, you need the schema.

If a binary format is going to be used, it should be optional - or perhaps there should be tools to convert the history file to/from a plaintext format.

Would like to see comments in configuration, Json doesn't support comments.
(comment deleted)
There is uclcmd [https://github.com/allanjude/uclcmd] which could do with some more work but was created with the intent of being a UCL equivalent of JQ.

Also since he’s the kind of person that a HN reader will probably Ike to know more about. The original author of the aforementioned uclcmd, Allan Jude [http://twitter.com/allanjude], is the former host of the TechSNAP podcast [http://www.jupiterbroadcasting.com/show/techsnap/], current host of the BSD Now podcast [http://www.jupiterbroadcasting.com/show/bsdnow/], a current member of the FreeBSD Core team, and co-authored not one but two books on the ZFS file system FreeBSD Mastery: ZFS [https://www.amazon.com/FreeBSD-Mastery-ZFS-7/dp/0692452354/] and FreeBSD Mastery: Advanced ZFS [https://www.amazon.com/FreeBSD-Mastery-Advanced-ZFS/dp/06926...]

UCL can be trivially transformed to JSON or YAML; ucl-tool supports this from CLI.
Supporting this, I don't think protobuf is a good format for storing history files. Backward compatibility is tricky with it - I don't think the history format is going to change all that much, but I think there were changes in history of fish shell like adding time field. If the choice would be on a binary format, I would much, much, much more prefer SQLite for that. Also, B-trees are perfectly fine choice for searching history, as they make prefix searches trivial.

TOML is definitely an interesting choice if a text format is deemed necessary however. Array of tables syntax should be a fine syntax choice for storing history.

In addition protobuf is designed for communications, not incremental updates in a local store. As such making things robust to store things on a development machine is non-trivial. SQLite is so much better for that. After Firefox switched to use it for its own history, most problems with history corruption disappeared.
I was about to say SQLite, it seems perfect - binary, fast, easy to update cheaply in place, immune to escaping et al problems (if you use prepared statements, not glue SQL with + of course), reliable, available in most languages (even for C and C++ the integration is trivial - it's a single pair of files drop in) and on the CLI, stable, the history data is very row/item oriented and not totally heterogeneous or free form, etc.

I totally drank the SQLite koolaid a long time ago.

History file may be read & updated simultaneously my multiple processes. Is that sufficiently safe from corruption with SQLite? (honest question, no FUD implied. same risks apply to alternatives too.)
You can ad extra fields to protobufs just fine, they just need to be added to the end of the definition.
For configuration I would very much prefer to have something that can be properly grepped/patched/generated with shell scripts if necessary. What openssh uses for its config mostly fulfill this, but ini file also are not that bad. Anything hierarchical like JSON/TOML/UCL etc. becomes very unattractive the moment one has to patch them from automated setup scripts.
Templates in configuration management can help with this a bit.
There pretty mighty tools around to grep/patch/generate JSON data with shell scripts and they are made to deal with hierarchical data.

https://stedolan.github.io/jq/manual/

http://jsonnet.org/

Both are single binaries, so easy to run them where you need it. I don't know comparable stuff for the other mentioned formats, whenever I need to deal with yaml in scripts i run

https://github.com/bronze1man/yaml2json

I would be totally fine with any format that can be converted to JSON on the fly. Of course I would love to have something like these tools more integrated within a shell, but the representing text format on the disk is not that important for me.

Long-time fish user here, I'll second this comment and implore that you choose TOML for the configuration format. TOML format is easy for users to understand, and well-written parsers for it exist in every programming language.
Thanks for bringing up UCL! Hadn't seen that before but I definitely need to try this in a few places.
What sort of syntactic changes?
Hi, another fish dev here!

We're open to a lot of things (except "make it fully POSIX-compatible"). We're still trying to not massively break everything, though.

The sort of things we've discussed include:

- Not expanding `{}` so you don't need to quote it with e.g. `find -exec {}` (currently this is read as a zero-element brace expansion, i.e. it expands to no argument)

- Removing the `?` single-character glob because it's apparently entirely unused and is another special character to remember (in fact we've also talked about removing `^` as a shorthand for redirecting stderr and `%something` process expansion)

- Allowing `$(command)` command substitutions, which could be used inside quotes as well (long term, these would replace our current `(command)` style)

- Possibly removing the special handling we have for $PATH, $CDPATH and $MANPATH (these are treated by fish as lists, which is nice in some ways and causes pain in others)

For a general overview, see [the fish 3.0 milestone on github](https://github.com/fish-shell/fish-shell/milestone/18).

No thanks, am happy with the shell as is.
Fish shell's design doc [0] was a huge inspiration in the design of pgcli [1] and mycli [2].

Thank you for leading the charge on modern command line design.

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

[1] https://www.pgcli.com

[2] https://www.mycli.net

Credit where credit is due, nearly all of the design doc was written by Axel Liljencrantz, the author of fish 1.x.
Does this mean... the link between the name and your nick is a coincidence?

Thanks for both your work on fish and for your blog!

I am learning Postgresl for the fun of it and I hadn’t heard of pgcli before. Thanks for mentioning it.
pgcli was a huge help to some former colleagues who had some trouble working with relational databases and SQL for the first time. I'm a big fan myself as well. Thank you for building a great piece of software.
Avid fish user since last 3 years. On feature I miss from bash is the `sudo !` to re-run previous command as sudo. Last time I checked fish didn't offer an equivalent. Either that or something similar will be useful
!! and !$ are the two miss most.

but similarly, fish user for the last 2+ years.

With !$ you can use Alt+. to write the arguments from the last command.
Alt+. is a bash (libreadline really) key.

In fish Alt+Up does something similar, but repeated presses iterates over all words of all commands rather than last words of bash commands. A big improvement is you can type some chars first and then Alt+Up only gets words matching this substring — like Up but word granularity! (Closest bash key is Ctrl+Alt+I)

If you don't mind the differences, and want Alt+. muscle memory to work in fish too, do:

    bind \e. history-token-search-backward
(plus Alt+Up doesn't work for me in linux console, Alt+. does)
This is easily achieved using a fish function: https://github.com/nyarly/fish-bang-bang

Unlike bash, fish even expands it in place, allowing you to make changes.

zsh also expands in place for double bang, as well as the ^match^replace thing, too. Probably others, but those are the only ones I use regularly.
Up, Home, "sudo "

Only one more key press than "sudo !" :)

While I like fish, I stopped using it because of a small convenience feature ZSH has.

With ZSH, I can run a command with a space at the start so it's excluded from history, even though its not saved to disk, the last command is still stored in memory so I can press Up to access it again.

This is handy when a mistake is made in the command means I need to run it again with some small change.

This feature seems to exist also in bash. I discovered it accidentally while wondering why my history did not include my last commands (copy/pasted with a leading space).
AFAIK it's not stored in history but also you can't go "up" and run it again which is what parent wants.
Right, only the last command is kept in memory. Run another command and it's lost (which is good IMHO)
Heh I have the opposite preference, I use space to ensure when pressing up it will not bring up that command, to not mistakingly run it when muscle memory will expect another command there (for mv and rm commands mostly)
Hey, thank you for contributing to one of my favorite pieces of software :) The Fish shell is my primary choice, because it's so intuitive and easy to use. I never encountered a situation where the Fish shell behaved contrary to my expectations. I do wish there was a native Windows version, because that's where I spend 50% of my digital time, but only because it's so great.
I tried fish and it seemed ok, I didn’t continue with it cause I needed to rewrite all my aliases and functions (work related not at home). From memory one was && vs “and” which we use a lot to chain commands. Something like implementing &&/|| would go a long way, compat command sub, closing if statements . I know it seems like a small thing to modify your aliases/functions but I would basically need to modify mine and be a maintainer for the shared ones. TLDR adddition transitionally compat with bash or zsh
I would love to see zsh navigation tools[0] be integrated in fish. There is a long standing issue in fish which is the support for CTRL-R history, while many are pondering on the UI of it. I would like to see znt's UI be adopted (not saying it's perfect, but quite a good starting point for user conversion).

[0] https://github.com/psprint/zsh-navigation-tools

I have switched to fzf for Ctrl-R history which does seem kind of similar.
Copy and pasted from another reply: "I still wish fish support && and ||, if only for the times when I copy and paste some one-liner off of stack overflow and have to rewrite it."

That and support for

    SOME_ENV_VAR=foo ./bar
(not having to prepend "env ") are what's stopping me from recommending fish to others.

Btw: Big thank you for fish, it's awesome!

Yes please, even if we have to opt in to this behavior with a patronizing env var :)
I really like that you have to use `env` in fish, since it's cross-shell - it works in bash/zsh/dash/whatever. The `A=b foo` syntax is an unnecessary appendix in the syntax that complicates matters while only saving 4 characters.
I agree and think the best fix would be if the syntax would be forbidden in bash/zsh. Problem is: Millions of code snippets on the Internet not using env.
For one-liners, typing `env ` before pasting is likely not too much work. For longer scripts, you'd have to rewrite much of the text anyway.
often there's stuff like

    cd build && LD_LIBRARY_PATH=../lib ./foo
:/

It's no dealbreaker though, I still use fish and love it :) Just a minor annoyance ;)

That syntax is from very early days of sh itself (predecessor of bash), IIRC. So removing it would break many scripts, as sibling comment by jhasse said.
It's not just to save typing - having an `A=b foo` form built-in instead of relying on an external program means `foo` can be an alias or shell function.
Agree with these, and would like to add one more:

  $(subcommand)
as an alternative to

  (subcommand)
PS: I have been using fish as my primary shell for about a year now, very happy with it. :)
Is there any planned work on the vi-mode command line edition ? This is the sole missing feature which make me miss bash from time to time.
Vi mode has been implemented since 2.2.0 (July 2015), although it's an ongoing work in progress - if there's something missing then we'd consider adding it (although nobody's going to reimplement Vim in fish - sometimes Alt-E is your best option).
Sure, but the current implementation has several bugs and could be refined, some motion command does not move where is expected (ie e b e b combos)
I'm very glad to see that getting rid of the magic path variable semantics is a possibility for 3.0 :)

Other than that, my biggest pain point with fish now is that it doesn't interact well with pkg-config (issue #982) and the workarounds for that are a bit awkward. eval is scary and may require double-quoting the non-pkg-config parameters, and string splitting can wrongly split inside quoted text.

&& is a major one. Also !! for sudo !!
Care to explain what this does? Thanks
!! is the last command, so sudo !! will run the last command as root.

e.g. apt install foo # you need root permissions to install, won't work sudo !! # will expand to sudo apt install foo, and it'll work!

It would be great if Fish supported &&. I know it has its own syntax for this but it's not particularly fun going through a command you copy pasted from elsewhere and swapping out all the &&s (I usually just end up firing up bash).
Fish's FAQ already explains why it doesn't use `!!` – it says that editing commands from history by pressing the up arrow is more memorable and flexible. I don't find it a problem to type “up Ctrl-A sudo” instead of “sudo !!”.
the main feature i use fish for is the syntax expansion, and history usage of it. The biggest gripe i have with it is the specific syntax. If fish would act more like a bash shell in case of syntax. ( i know i would need a totally different shell). But it could replace the fish for me in an instant. everywhere. Anyways. Thanks for the fish.
What are some things to look forward to for Fish 3.0?
Thanks for it! I am also using Fish happily for interactive terminal work. Not so much for scripting as I am lazy to learn the new syntax.

What I don't like is that after hitting Tab twice when doing path completion, the list of possibilities comes out, allowing arrow keys to be used for selection. The problem is that it requires pressing Enter to confirm the suggestion and I fear of executing the command with incomplete path prematurely (it's just one more Enter hit away).

Related: xonsh (http://xonsh.org)

It's a Python-based shell that attempts to be somewhat bash-compatible (for ease of use over, e.g., IPython). Instead of making a new scripting language (fish), go all in.

Pros: scripting is amazing. ( while True: ls ~ ) Cons: can be a bit slow (because Python interpreter).

I definitely prefer zsh. I just feel like Fish tries too hard and it's just awkward to switch between fish and bash when frequently switching between different machines.
Loved it a few years ago, stopped using it when I started using conda and it didn’t support switching into those environments. I’ll try again hopefully that’s fixed.
The great thing about fish for me is that comes so nicely set up on first install that, a few path additions aside, I don’t have to mess with it. Any time spent on shell configuration is time wasted from my perspective.

This in turn means I’m willing to install it with no hesitation in all my local and remote logins, so I have a uniform simple setup everywhere.

My biggest gripe is fish (I think its Fish?) trying to do DNS lookups when I hit `ssh user@hosting-<tab><tab>`

Is there a way to disable this?

I've used fish as my shell for over five years. Thanks to the developers!

One issue is the behavior of globs. I often want to do "scp host:directory/* ." but you can't do that in fish, so I drop to bash. That's pretty much all I drop to bash for.

scp host:directory/\* .
Also possible:

    scp 'host:directory/*' .
(comment deleted)
Note that the reason bash works here is actually a bit ugly.

Like fish, it'll interpret an unquoted asterisk (sorry HN formatting) as the glob character. So it tries to match pathnames to `host:directory/`.

Only the default bash behavior (if "nullglob" and "failglob" aren't set) is to pass the literal glob expression if no match could be found.

So once you `mkdir host:directory; touch host:directory/file` (which you can do - this is unix, so almost all pathnames are allowed), this will be broken.

This means you _should quote the token_ in bash, which is exactly what you should do in fish.

Note: This is also why you might see code like the following in bash:

    for file in *; do
        if test -e "$file"
See http://mywiki.wooledge.org/BashFAQ/004 and http://mywiki.wooledge.org/glob#nullglob for more info.
The redoxOSers are busy breaking the stupid parts of POSIX, and their shell, ion , is slowly coming in, finally, as the 'shell of the 00's'.
Ctrl-R and Ctrl-S please. Using the arrow keys for searching through history quickly (i.e. without leaving the home row) sucks.
You can bind and rebind most keys. Are those two not possible?
+1. If some developer reads this, Ctrl+R is the only missing thing I can't imitate from bash.
I know this might not be what you'd want, but I'm doing this with fzf[0]. I have something like this as an alias:

  eval (cat ~/.local/share/fish/fish_history | grep 'cmd:' | cut -c8- | fzf --tac)
and then I simply bound it with `\cr`. It doesn't exactly replace Ctrl-R functionality but it suits my need.

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

It's not the same as ctrl-R/ctrl-S, but you can use ctrl-P/ctrl-N to scroll history like with the arrows without leaving the home row.
you dont really need Ctrl-R in fish. Just type the command you are searching for and hit the up arrow key. Same effect
Ctrl+R is more convenient if you are a touch typist. Using an arrow key forces you to take your right hand off from the home row.
Wow! This is great!

Wait... Is whitespace significant?

No, not to my knowledge! It does autoindent things for you when you’re editing multiline functions inline, but whitespace is fortunately not significant.
Great! It's one of the things that irritates me in Python (whitespace used as scope delimiter).
I'd go so far as state that I cannot fathom the decision to assign deep semantic meaning to a set of invisible symbols.
Love fish, especially because of the easy configuration and out of the box features. No need for complicated frameworks or curated dotfiles. There are two syntax changes I’d love to see:

1. Support for last command by !!, as in `sudo !!`.

2. Ability to search history from a partial command like `git checkout`, where up arrow would step backward from the present.

I wish all my tools were as friendly as fish!

>2. Ability to search history from a partial command like `git checkout`, where up arrow would step backward from the present.

We have that feature, and it's enabled by default. Just type the partial commandline and press up-arrow. Or do you mean something slightly different?

That's true. Sorry for my poorly-worded English. For a small example:

    $ ls -la foo
    $ ls -la bar
    $ ls -la /
When I type `ls -l` and hit the up arrow, my first result is `ls -la bar` not `ls -la /`. This is a small problem but sometimes annoying, especially after using other shells that work differently.
In this case, what most likely happens is that the first result is offered as the suggestion - i.e. the greyed-out part in the commandline. To accept that, press right-arrow (with the default bindings, of course).
I use fish as my primary shell. I've ran into a few issues where it broke existing fish scripts, and, uh, let's just say some of the developers (not 'ridiculous_fish) were less than stellar in their response. (I get it. It's open source. You don't owe anyone anything: but you also don't have to be a jerk about it, and I also don't owe you using your software.)

My original reason for using fish was onboarding junior engineers. I had a pretty fancy zsh/emacs setup, and they'd ask me how to make their shell do that (reminder: on macOS you get bash3.2 by default!). So I switched to fish/spacemacs, so the answer isn't "uh sure you can rsync 50MB of accrued elisp".

Result: I have a nice zplug[0] setup now:

  > cat /usr/local/opt/zplug/packages.zsh
  zplug "zsh-users/zsh-syntax-highlighting"
  zplug "zsh-users/zsh-history-substring-search"
  #zplug "zsh-users/zsh-autosuggestions"
  zplug "zsh-users/zsh-completions"

  #zplug "plugins/git", from:oh-my-zsh
  #zplug "plugins/github", from:oh-my-zsh
  #zplug "plugins/fossil", from:oh-my-zsh

  #zplug "plugins/docker", from:oh-my-zsh
  #zplug "plugins/docker-compose", from:oh-my-zsh

  #zplug "plugins/python", from:oh-my-zsh
  #zplug "plugins/pip", from:oh-my-zsh

  zplug "plugins/lein", from:oh-my-zsh

  #zplug "plugins/autojump", from:oh-my-zsh
  #zplug "plugins/command-not-found", from:oh-my-zsh
  #zplug "plugins/gpg-agent", from:oh-my-zsh
  #zplug "plugins/ssh-agent", from:oh-my-zsh
  #zplug "plugins/thefuck", from:oh-my-zsh

  #zplug "plugins/aws", from:oh-my-zsh
  #zplug "plugins/osx", from:oh-my-zsh
  #zplug "plugins/battery", from:oh-my-zsh
  
  zplug "tweekmonster/nanofish", as:theme
Still easy to reproduce. Maybe consider some of those plugins. You don't have to give up being POSIXy. Whether or not that's good or bad, I leave up to you :)

(Commented out bits are things I'm playing with: mostly to improve shell startup time.)

[0]: https://github.com/zplug/zplug