1. 63
  1.  

  2. 29

    Is fish amazing or is it just that bash is so primitive that we are are easily impressed by simple features?

    1. 40

      Fish’s slogan is “finally, a command line shell for the 90s” for a reason

      1. 11

        I love it. This kind of attitude actually makes me more inclined to try it.

        1. 7

          It’s a bit optimistic, given that fish is still not as good as the transcript panel in Smalltalk-80, running on an Alto in 1980s. There’s a similar reason that I’ve used ‘dragging the computing industry kicking and screaming into the 1980s’ as a subtitle for a lot of talks I’ve given in the last few years.

          1. 1

            “The 1980s are here. They’re just not evenly distributed.”

        2. 2

          Yes?

        3. 21

          for me, the #1 fish feature is the fact that I can get a nice shell with all these features out of the box! I’m sure you can get something similar with oh-my-zsh or another package, but on my machines I just apt install fish and I’m done.

          1. 19

            +1

            Another useful feature are abbreviations: https://fishshell.com/docs/current/cmds/abbr.html. These are like aliases, except that they expanded in place. That is, you type sw but what you get is git switch. That’s pretty useful to keep the cognitive load low, as what you read are full commands. Also helpful when you want to edit command slightly.

            1. 3

              This looks nice as a replacement for some of my Fish functions. Thanks for sharing!

              1. 1

                I never know such a thing. I might move some alias to abbrev. To keep the cognitive load low. Thanks.

              2. 15

                I’ve been using Fish since 2015, and it’s been great. Fish not being POSIX compatible hasn’t been an issue in practice, though I don’t do a lot of shell scripting to begin with. If somebody is curious about my Fish configuration, you can find it here.

                1. 4

                  For me the lack of sh-compatible syntax has been a real problem, to the point where I switched to bash at work. Fish does have the best user experience I’ve seen, but the need for specific Fish scripts is a problem, in particular with Nix or any tool that you need to load from your profile. There are wrappersz like bass, but they don’t always work and have overhead.

                  1. 30

                    Just because fish is your interactive shell doesn’t mean that you need to start shell scripts with !/usr/bin/env fish.

                    1. 9

                      I never understood what people is doing all day in their prompt that needs POSIX compatibility. The syntax to call commands is the same.

                      I think it is mostly a meme or a simple matter of running copy pasted scripts from the web and not understanding how interpreter resolution works or that you can manually define it.

                      1. 1

                        Not necessarily whole scripts. Sometimes you want to paste just a couple commands into the interactive prompt.

                      2. 3

                        But for stuff like Nix, don’t you have to run the setup scripts in your interactive shell with source or equivalent, so they can set environment variables and such?

                        1. 3

                          In Unix, all child processes of a process will inherit the parent’s environment. You should be able to write all your scripts as POSIX compliant (or bash compliant) and run them from inside fish without an issue, as long as you specify the interpreter like so: bash myscript.sh

                          1. 8

                            The problem, if I understood it right (I’ve never used things like Nix) is that these are not things you’re supposed to run, but things you’re supposed to source. I.e. you source whatever.sh so that you get the right environment to do everything else. Sort of like the decade-old env.sh hack for closed-source toolchains and the like, which you source so that you can get all the PATH and LD_LIBRARY_PATH hacks only for this interactive session instead of polluting your .profile with them.

                            1. 1

                              I see, that makes sense. I guess I didn’t consider that, wonder how the activate script generated with a Python virtual environment would work with Fish. Even a relatively fancy .profile file might be incompatible with Fish.

                      3. 8

                        I usually just switch to bash when I need to run a command this way. And honesty I’m more annoyed at commands like these that modify your shell environment and thus force you to use a POSIX-compatible shell, than I am at fish for deliberately trying something different that isn’t POSIX.

                        1. 1

                          Fortunately some commands are designed to output a shell snippet to be used with eval

                          eval $(foo) # foo prints 'export VAR=bar'
                          

                          In that case you can pipe output of foo to Fish’s source

                          foo | source
                          
                          1. 2

                            No, that’s exactly what you can’t do, the code won’t be valid for source-ing (unless those commands specifically output csh-style rather than posix-style script)

                            Though apparently these days fish does support the most common POSIX-isms

                            1. 1

                              I mean only the case where you set env variables (like luarocks path)

                        2. 4

                          I also had problems with bass. It was too slow to run in my config.fish. However, I switched to https://github.com/oh-my-fish/plugin-foreign-env and it’s worked perfectly for me. And you don’t need oh-my-fish to use it — I installed it with the plugin manager https://github.com/jorgebucaran/fisher.

                          1. 2

                            Ah, I hadn’t seen this one, if it succeeds to setup Nix then it’s party time!

                            1. 3

                              Not a fish user, but since you’re a Nix user I would also recommend checking out direnv which has fish support. For nix in direnv specifically I would also recommend something like nix-direnv (and several others) which caches and also gcroots environments so overheads are next to negligible when things remain unchanged.

                            2. 1

                              That looks good enough to make me want to try fish again. I had not seen it last time I tried fish. Thanks for pointing it out.

                        3. 10

                          If I were to add something:

                          • Multiline editing: While you can write multiple lines in other REPLs, like Bash and Python, you can’t navigate up and down in what you type, and you can’t retrieve a multiliner back in its full glory. Because they all use readline. Fish has basically reimplemented readline. A simple multiline command:
                            begin
                                make
                                and sudo make install
                            end
                            
                            I write multiliners like this all the time, even quite long ones, because it’s easy to edit the previous command. When it’s time to save, just make it a function and funcsave it.
                          • Alt+Left/Alt+Right to go back and forth between previous directories.
                          • Bracketed paste: It used to be that when accidentally pasting some substantial text in the shell, the shell would immediately go on to execute each line of it as a command, without waiting for your enter key. Bracketed paste is a protocol between the terminal and the shell, that most terminals support, that lets the shell distinguish between newlines and the enter key.
                          • End of quoting hell (POSIX shell’s big mistake): Fish doesn’t just interpret whitespace and glob characters in the contents of variables. That’s of course completely nuts. Instead, every variable is an array, so you don’t need word splitting and this evil kind of glob expansion.
                          • Nullglob and failglob by default: Fish doesn’t just pass failing glob expansions unexpanded. How many iterations does this iterate?
                            for i in nonexisting/*
                                echo $i
                            end
                            
                            Zero! And does this execute ls at all?
                            ls nonexisting/*
                            
                            Nope!
                          1. 9

                            The autocompletion is the killer feature for me as well. I used Bash for years without knowing about Ctrl+R history search, and I never learned how to search backwards with it. Fish just searches the history, so you don’t have to decide that before starting to type, and you don’t need to learn how to use the arrow keys to iterate the results. Fish made me instantly more productive than I ever was with Bash.

                            1. 3

                              I would wager that fish style autocomplete is an objective indisputable advantage. Being able to look at the man pages documentation as you type is practically non intrusive and adds value that you don’t have in other shells.

                              Fish history and bash’ i-search history always felt limited to me. My problem with them is that I can only look at a result a once. Peeking through history never felt smooth to me. Until I found this: https://github.com/oh-my-fish/plugin-percol

                              This is the one thing that makes me maintain a fishconfig rather than just using fish as is out of the box. I have also written this https://github.com/plainas/icl to keep frequently used commands neatly organised and documented.

                            2. 6

                              I think fish’s strength is its lack of compatibility, because it can get rid of at least a few of the really bad parts of shell scripting. Unfortunately, its lack of compatibility is also its weakness.

                              I used fish for a couple months before switching back to bash. For people who like the interactive bits of fish, but for whatever reason would rather use bash, I recommend trying out ble.sh:

                              https://github.com/akinomyoga/ble.sh

                              1. 5

                                I love Fish.

                                ZSH is very configurable, and with a deep enough pile of plugins and configuration you can achieve much of what Fish does out of the box. The advantage of Fish is, you get all that seamlessly out of the box.

                                The only two plugins I’ve installed are the tide prompt (reimplementation of powerlevel10k) and fzf for fuzzy history search.

                                Broken POSIX compat isn’t a huge issue for me. I always had to look up documentation when using those features in bash/zsh, and I can always start a bash subshell if some build script is acting picky.

                                1. 4

                                  Reading the comments here, lack of POSIX compat really does seem to be the third rail of acceptance criteria for shells. I think it reflects larger attitudes in software engineering where only a certain amount of “conceptual disruption” is collectively tolerated.

                                  “But BigCorp has gigabytes of POSIX shell scripts!”

                                  Okay, nobody said you have to set your login shell to fish though.

                                  1. 3

                                    I switched a while ago, and it’s great. I really don’t miss zsh, and I was never a bash user (switched from ksh to zsh in the 1990s). I understand the path dependence that means that we are going to have POSIX shells until the heat death of the universe, but I am so happy to have extricated myself from it.

                                    1. 3

                                      The last time I tried fish (in ~2012 mind you), I enjoyed the out of the box experience, but I never managed to make its completion menu 2-dimensional. When completing most things, my ZSH config will print out suggestions in enough columns to span my screen, and I can navigate to the option I want quite easily with all directions on the arrow keys. In fish, it would just print a 1-dimensional list, with only up-down navigation. This sounds like a small thing, but my ZSH config already did all the fish stuff like “busted syntax or unknown command is red” and “it completed all the commands I use intelligently”, so I didn’t stick with it.

                                      I think it’s a good option if you are fine with dropping POSIX compliance (eg, copy pasting shell examples from your company’s wiki) and don’t want to invest in setting ZSH up well (many people use oh-my-zsh which is SO slow in my experience).

                                      1. 4

                                        Check UPDATE 1 to my blog post about ZSH shell setup here:

                                        https://vermaden.wordpress.com/2021/09/19/ghost-in-the-shell-part-7-zsh-setup/

                                        You can actually make zsh(1) to behave like fish(1) shell.

                                        I like fish(1) shell bit I often use POSIX syntax for loops for various things and it really breaks my way of work.

                                        Regards.

                                        1. 2

                                          The first time I used fish, I hated it so much I’ve never given it a second chance.

                                          I just hated how different it was from POSIX shells for interactive use (I’ve never scripted with it). But I think that’s it’s selling point to some people.

                                          To each their own I suppose.

                                          1. 12

                                            The POSIX incompatibility is less annoying than it used to be. For me, the most annoying things was && and || not working — that’s been fixed since fish 3. I also recently discovered that VAR=foo cmd ... works now, whereas before you had to do env VAR=foo cmd ....

                                            1. 2

                                              export VAR=foo works as well

                                          2. 2

                                            I just installed fish and git sw<Tab> completed slower than zsh.

                                            1. 1

                                              I also highly recommend checking out xonsh

                                              1. 1

                                                I think people overestimate how much configuration zsh needs to do “fish things”. You don’t need oh-my-zsh, you don’t need “zsh package managers”, all you really need is zsh-history-substring-search and zsh-syntax-highlighting.

                                                1. 1

                                                  I used mostly-not-configured fish for many years. Fish is nice; I really liked it. A minor con is that if a tool requires a line or two of .rc, you might have to adapt it from a bash example.

                                                  A few years back I switched to mostly-not-configured zsh in order to stay somewhat more immersed in POSIX. Looking back, I do value having spent more time with standard syntax for pipelines and subshells and so on. But if you feel like you’ve got all that internalized, go fish.