Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Ooh switching to Fish from Bash could be a nice weekend task. Any tips on common tripping points?



Do it! You will never look back.

The most common tripping points are the minor adjustments in syntax, probably the biggest one being command substitution:

Bash:

    $ echo “$(ls -al)”
Fish:

    $ echo (ls -al)
You get used to it though.

Another thing many bash-ers sometimes miss is the !! substitution, e.g.

    $ apt update
    # permission denied
    $ sudo !!
This doesn’t work in fish, BUT fish does offer a handy keybinding out of the box to prepend ‘sudo’ to your current command line (submitted by yours truly). So when using fish, you’d handle the above scenario like this:

    $ apt update
    # permission denied
    # press Up or Ctrl-P followed by Alt-s
    $ sudo apt update
There are so many other great things I love about fish, but this comment is already long enough.

Be sure to read (or at least scan) through the user guide on their website. It’s an easy read and not dense. You can also view it at any time by running `help` from inside fish.

I can’t recommend fish highly enough, I’m excited for your journey :)


Adding this to your config.fish will give you !! and !$ in fish

    function bind_bang
        switch (commandline -t)[-1]
            case "!"
                commandline -t $history[1]; commandline -f repaint
            case "*"
                commandline -i !
        end
    end

    function bind_dollar
        switch (commandline -t)[-1]
            case "!"
                commandline -t ""
                commandline -f history-token-search-backward
            case "*"
                commandline -i '$'
        end
    end

    function fish_user_key_bindings
        bind ! bind_bang
        bind '$' bind_dollar
    end


I’ve been a fish user forever, but the lack of support for sudo !! has never made sense to me. I’m glad to finally know that there’s a 2-keystroke alternative.


In regular Bash just press up and opt-up. If that doesn’t work your key bindings are bad and you should fix them. I never understood why anyone would ever use !! instead of something that is fewer key presses and more universal.


Another common thing I had to learn when I switched to fish, is the basic for-loop construct. Luckily it's super simple, here is an example:

   for f in (ls -1 *py); echo $f; end

One more thing to note is setting ENV var FOO to value bar is

   set -x FOO bar
Note no equal sign. To delete an ENV var use `set -e FOO`.

If you want to set ENV vars permanently for your login shell, the file to edit is `~/.config/fish/config.fish` and the syntax is:

   set -gx PATH  $PATH /some/new/path

which means set var PATH to whatever PATH contained before with /some/new/path appended to it.


I used fish for two years or so, and recently switched back to zsh, mainly because Fish is too slow to load, and this is not something the developers are willing to fix. The problem I had was that I needed to load a “bare” shell, without plugins or anything else, but this is not functionality fish provides, and judging from the developers’ comments something they are not going to.

So I spent a day migrating my fish config to zsh, and am much happier now.


This is interesting as I had the exact opposite experience. Fish is screaming fast for me compared to zsh, primarily because I don’t need to use any plugins to achieve all of the functionality that I needed to use many plugins to achieve in zsh. The totality of my fish config files, not including functions, is maybe a couple dozen lines [1].

Regarding a bare shell: perhaps I’m not understanding your exact needs, but fish is able to check whether or not it’s being used interactively with `status is-interactive`, so you could certainly try wrapping all of the plug-in loading machinery around a guard like this.

[1]: https://git.sr.ht/~gpanders/dotfiles/tree/master/item/.confi...


If you install oh-my-fish, you can just use this plugin for !! https://github.com/oh-my-fish/plugin-bang-bang


Thank you so much! HN at its best!


You might want bass (https://github.com/edc/bass) or replay.fish (https://github.com/jorgebucaran/replay.fish) if you need to run bash scripts that modify the shell. I personally use replay.fish (although I guess I haven't updated in a while since my version is still called "bax").


If you want a plug-in free solution, you can try the following:

    $ exec bash -c ‘source script.sh; exec fish’
This has some caveats and won’t work in all cases (both bass and replay.fish go into more detail), but this is what I use and it hasn’t failed me yet.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: