Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Fish shell (fishshell.com)
451 points by Aloha on May 18, 2015 | hide | past | favorite | 182 comments


Hey, I'm the lead dev of the fish shell. There's some great discussion in this thread!

For those who are interested, the fish shell is about to release version 2.2, a very significant release that wraps up eighteen months of development. You can try the beta now: http://fishshell.com/beta/

A sampling of new features:

- vi mode (yay!)

- Abbreviations, fish's take on aliases. They expand as you type them.

- A new "inline" pager, inspired by zsh. It's searchable and supports progressive disclosure. See it in action: https://www.youtube.com/watch?v=ncVWbT-jWAw

- A redesigned theme and prompt chooser: http://fishshell.com/beta/assets/img/screenshots/web_config....

- Tons of new tab completions!


BTW, you should mention https://github.com/fish-shell/fish-shell/wiki/Nightly-builds after "You can try the beta now", because I cannot get beta at http://fishshell.com/beta/


Unless you want to install it from the tar.gz file


Amazing stuff! Thanks to all the Fish team for your amazing work. I've been a Fish user for 3 years and wouldn't use anything else. The vi mode is a killer feature for me, so cool!

I couldn't find any information about the team though, maybe it would be a good idea to include some kudos on the website / on github just to show that real people are involved in this project. Personally, it always makes me be grateful.

Cheers!


After updating to v2.2b1 using instructions at https://launchpad.net/~fish-shell/+archive/ubuntu/beta-2, these occurs to me in my original conf.fish file:

========================================================

# count the number of the files in the dir(not sub.), use tree | wc -l for subdirs # alias lsc ls:command not found ~/.config/fish/config.fish (line 67): # alias lah 'la --color=yes --sort=time -lh | head' # count the number of the files in the dir(not sub.), use tree | wc -l for subdirs # alias lsc 'ls -all | wc -l' ^ in function 'fish_prompt' called on standard input

in command substitution called on standard input

Warning: Identity file

alias cp cp not accessible: No such file or directory.

Warning: Identity file

alias mv mv not accessible: No such file or directory.

Warning: Identity file

alias rcp rsync not accessible: No such file or directory.

unknown option -- -

usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]

           [-D [bind_address:]port] [-E log_file] [-e escape_char]

           [-F configfile] [-I pkcs11] [-i identity_file]

           [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]

           [-O ctl_cmd] [-o option] [-p port]

           [-Q cipher | cipher-auth | mac | kex | key]

           [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port]

           [-w local_tun[:remote_tun]] [user@]hostname [command]
>

========================================================


Yikes! I'll open an issue and make sure this is addressed for the 2.2 release. Can you please post your config.fish in a gist?



Thanks, I opened an issue at https://github.com/fish-shell/fish-shell/issues/2073 . I wasn't able to reproduce any problems with your config.fish, so if you feel up for chiming in that would be great.


I haven't pushed my local conf.fish file to Github for months (but I think it is no big difference), I'll test the v2.2-beta later at home in my local.fish and push it to Github, maybe you can test it then.


[deleted]


Some background: the "symlink problem" refers to this: http://fishshell.com/docs/current/faq.html#faq-cwd-symlink

In bash, if you cd into a symlink and then cd .., you get back to where you started. But fish will resolve the symlink, and so it will take you to the destination's parent.

The price bash pays is inconsistencies between external commands and builtins. For example, `ls ..` can output something different than `cd .. && ls`. This is because the kernel maintains the cwd as an inode, not a path.

I don't know of anyone who is wedded to the existing behavior. If you feel strongly about it or have ideas for how it ought to work, please comment in the issue! https://github.com/fish-shell/fish-shell/issues/1957


Could you elaborate on 'the symlink problem?' I just installed 2.2 and symlinks seem to function as expected to me.


It sounds amazing.

Hey, since you are the lead dev of the fish shell, a serious problem occurred to me weeks ago, I was compiling a QT client in fish, and there is already an environment value called `LD_LIBRARY_PATH` (including other values the compilation needs) defined in /etc/ld.so.conf.d/ and /etc/profile.d/ but fish cannot find them, if I use `set -g ...` to set it in fish shell prompt and then do the compilation, it will work, it took me a lot time to figure it out that this is the problem of fish-shell, the weird thing is, there is already one line `#!/bin/sh` at the beginning of the compilation script (it is a bash script called build.sh), so it should be executed under sh which is bash in my CentOS.


Thanks for sharing this. The files in the *.d directories are bourne-syntax, and so fish can't understand them; that's why fish doesn't read them (excepting /etc/paths.d).

bash only reads the files in /etc/profile.d when launched interactively, so those files won't be read for #!/bin/sh scripts. Of course, if you launch the script from an interactive bash session, the script will inherit the variables that the profile.d files set up.

As an aside, this zoo of configuration files is something that fish tries to avoid. fish reads its config files unconditionally, and leaves it up to the file to branch on whether the session is interactive.


/bin/sh isn't BASH always ?? I'm on a Debian derived Linux:

$ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Feb 19 17:51 /bin/sh -> dash


Any chance that we'll be able to have fish not resolve symlinks in the future? This is the only problem keeping many people from using it.


Thanks!

I used fish years (2006/7 era) ago as my default shell, and I really appreciated the functionality in helping to make unix easier to use.


I'm curious - how does the theme stuff interact with choosing different ANSI colors in a terminal emulator? Is it using ANSI colors at all for those complex themes, or specifying RGB colors instead?


The themes are specified with RGB colors, and fish tries to pick the closest color supported by the terminal. It can do the 14 ANSI colors and the xterm 256 colors. fish 2.2 adds support for 24 bit color, which a few terminals can do (Konsole, iTerm2).

fish has a set_color builtin which accepts RGB hex. This makes colored output easy: `set_color 69F; echo 'I am light purple!'`


Seriously looking forward to this release! Been an avid user for over a year now and absolutely love this shell. Still get the odd strange look when I mention what I use though :)


Can you explain why your website requires JS?


Great work!!


Hi, can you tell how it competes to cmder and iterm? I use these currently in windows and osx


Not sure about this (I haven't used either, just looked at their sites), but I believe those are terminal emulators. They're the thing that displays the shell and handle input and copy/paste etc.

The shell is what actually handles key presses and produces the output (handling commands, input/output redirection, etc).

They're not the same thing - I bet you could use fish inside cmder or iterm.


Ah okay now I get it, so it's comparable to bash or zsh


I'd say it doesn't since neither of those are shells. They're both terminal emulators that run a shell within them, usually bash for linux/mac or cmd for windows.


I definitely recommend fish to every newcomer to Unix. It has sane defaults, colorful output, and so many features that work out of the box.

That said, there is a long-standing issue regarding inline environment variables.[1] Briefly speaking, fish does not recognize the `NAME=value command` form. So you should use `env` to work around this. This may not be a deal breaker, but I'm a bit annoyed, and migrated to zsh.

I would call zsh the opposite to fish. It has insane defaults, is highly customizable, and has so many features that are initially disabled. After hours of configuring it, I loved it.[2] Since then whenever I set up a new Unix machine zsh has been the first thing to install.

So, I would recommend zsh for the people who are used to Unix. If not, or you don't bother to customize it, there's always fish. There is no place for bash.

[1] https://github.com/fish-shell/fish-shell/issues/438

[2] https://github.com/barosl/baroslized-settings/blob/master/.z...


Using `env` is very much a feature, not a bug. It's part of fish's philosophy to use programs rather than builtins wherever possible. It's good practice to use `env` even when using other shells.


> It has insane defaults, is highly customizable, and has so many features that are initially disabled.

Ah yes, the Emacs and Vim school of configuration.


Fish is great. I used it for a couple of years, right up until I had to install a software system that made extensive use of bash scripts that were incompatible with it. At the time I was in too much of a hurry to figure out how to tell the software to explicitly use bash, or something along those lines.


As a rule of thumb you should make fish the default shell for your terminal emulator and leave bash as the login shell. This will let all the system configuration scripts work just fine.

The only time when POSIX incompatibility still hurts is if your workflow requires you to be source shell snippets.


Why would a software system that relies on bash not explicitly use bash for its scripts?


Bad developers. For example, I used Arch Linux for a number of years, where `/bin/sh` is a symlink to bash. Switching that to point to `dash` broke a number of programs both in the official repositories and the AUR. A lot of shell scripters can't spot a bashism, and just as many don't know that other shell syntax even exists.


That's a different problem, though. /bin/sh must point to a sh-compatible shell. fish is not a sh-compatible shell. Therefore, any script using /bin/sh will never attempt to run as fish (as /bin/sh will never point to fish).

The reason I'm having a hard time imagining how a scripting system that relies on bash would fail with fish is because I can't imagine how one would actually write a script that is executed with the user's login shell. There's no #! line that would do that by accident.


There's just one scenario: a completely absent #! line.

It's an easy fix, just add the line, otherwise 0755 scripts with no #! do execute using the current shell.


That doesn't work for me (in Fish).

  > cat foo
  echo wat
  > ./foo
  Failed to execute process './foo'. Reason:
  exec: Exec format error
  The file './foo' is marked as an executable but could not be run by the operating system.
It does however work in Bash. So this appears to be a bash-ism, rather than an OS feature.


Ah, bummer. I tested in csh too but not fish.


More likely, and somewhat less judgmentally, developers that are ignorant of the distinction.

Unless you want to define "bad" as "ignorant of some facet of computing" in which case we all fit.


I can't think of any other definition of "bad" when it comes to programming. But I do appreciate your sentiment and realize I was being unjustly negative.


Just to add to the first line, it also seems fairly well-commented in the code, at least the couple pieces I've looked at. This is really good for me as I often check the source first and helpful (or any) commenting is quite rare.


>There is no place for bash.

Just curious, why do you say this? I've used bash for years for basic command line things and now it sounds like I've been missing out on great features that other shells have.


Sorry if my words were too strong. I said that because I like tools that do a particular job well. bash might be a middle ground tool that has moderately sane defaults and features. However, in other words, bash is inferior to fish with regard to easiness, and is worse than zsh with regard to feature set. I'm not a fan of such a tool.

I believe the world could have been a better place if they adopted fish as a default shell.


Interesting. I'll have to give both of those a try.


I used to use fish, and emacs. But when I switched to vim, I had to switch away from fish as well because of its lack of vi bindings. It is a little disappointing to go back to using bash, but as long as bash-completion is working, it's not really a big issue. Of course, I do miss the syntax highlighting. (I would use zsh, but it provides little benefit over bash out of the box and is slower (oh-my-zsh is unbearably slow to start, too).)

There are a few things that, while I understand why fish is missing them, I wish would be added:

- vi-mode, obviously

- Control+R. It is annoying to have to guess how much you must type before hitting the up arrow, instead of having it dynamically displayed. Same goes for zsh vi-mode's ? command.

- Well more of a removal, but the backslash in single-quoted strings. I'm used to typing '\', and that's not possible with fish. Additionally, to get one backslash in any sort of regex (sed, grep), you need four backslashes.

- Goes without saying, but bash-completion. Fish's completion is mostly history-based, which is great for repeatedly running the same command, but terrible for discoverability

- "$()" and any non-splitting command substitution. Currently, it is impossible to pass a multi-line string from a command substitution as a single argument. Which, it may be argued, should be done by piping, but sometimes it is useful to have stdin.

- More extensibility in general. I'd like to be able to customize my shell just as much as I can customize my WM. Probably more.

Honestly, it was easier to go back to using bash than I thought it would be -- it was almost a relief. fish just feels more polished and clean, especially with regard to escaping, but it misses some very important features.

Edit: I heard that there is a vi-mode now. Sounds interesting, but I don't really feel like installing it at the moment, and if I ever try another shell it'll probably be zsh.


> vi-mode, obviously

As you said at the end, Fish does have this. I don't know if it's full-featured enough for you though.

> Control+R. It is annoying to have to guess how much you must type before hitting the up arrow, instead of having it dynamically displayed

When you start typing a command-line in Fish that matches a previously-typed command, it automatically shows the rest of the line as an available completion, and pressing ^F or the right arrow will complete it for you. The lack of this functionality actually really kills my ability to use any other shell.

> Currently, it is impossible to pass a multi-line string from a command substitution as a single argument

Not actually true. If you set IFS to '' then that disables command substitution line splitting. That said, it is not well-known and is rather awkward. This is a known pain point with Fish today.

> More extensibility in general. I'd like to be able to customize my shell just as much as I can customize my WM. Probably more.

It's really hard to know what you're asking for here. What isn't extensible enough for you? What do you wish you could do that you can't?


> When you start typing a command-line in Fish that matches a previously-typed command, it automatically shows the rest of the line as an available completion, and pressing ^F or the right arrow will complete it for you.

^R is more powerful, though; it matches at any point in previous commands, not just at the beginning.

> The lack of this functionality actually really kills my ability to use any other shell.

You can achieve that behavior in readline (which is used by bash, python shell, etc.) by changing the up/down arrows from previous-history/next-history to history-search-backward/history-search-forward. In ~/.inputrc:

  "\e[A": history-search-backward
  "\e[B": history-search-forward
Note that you can still use ^P/^N for previous-history/next-history (or you can remap "\C-p"/"\C-n" as well).


> ^R is more powerful, though; it matches at any point in previous commands, not just at the beginning.

That's how it works in Fish as well.

    user@system ~> echo wow
    wow
    user@system ~> echo something
    something
    user@system ~> wow█
...press the up arrow and the current line becomes...

    user@system ~> echo wow█


In bash, you hit Ctrl-R on the empty prompt and type "w":

    (reverse-i-search)`w': echo wow
Hit return to execute, or any motion keys to start editing. It was the first thing I missed in Fish.


In fish, you type "w" on the empty prompt and hit Up:

    > echo w̲ow
Hit return to execute, or any motion keys to start editing. As long as you don't move sideways, you can repeatedly press up or down to navigate history. The underline is actually a highlight hinting at the substring match in the line.

The difference is that typing an additional character after having moved in the history will start editing, appending the character to the line, instead of appending to the criteria.

What I miss in all of them is looking for a fuzzy match instead of a substring match.


I'm not sure how that is functionally different to mintplant's example?

In fish you just type 'w' hit the up arrow and then hit enter to execute or any motion keys to edit. The same number of keypresses as well.

Am I misunderstanding?


Discoverability. With fish i would have to type something that would be a good match to the command i want to re-run before pressing up. With bash i type ctrl+r and start typing and i can continue to type until it's narrowed down to the correct command.


> kills my ability to use any other shell

zsh definitely has this command, which I absolutely adore to be honest. ^R is one of my favourite features of the shell in general.


> You can achieve that behavior in readline

No you can't. What I specifically described was the autocomplete of the line, not the ability to search history (which is manual complete instead of autocomplete).


> - Control+R. It is annoying to have to guess how much you must type before hitting the up arrow, instead of having it dynamically displayed

It's not anyone's cup of tea, but I'm using percol to get similar functionality:

(taken from oh-my-fish)

* pip install percol

* make a function like this:

    function percol_select_history
       history|percol|read foo
       if [ $foo ]
           commandline $foo
       else
           commandline ''
       end
    end
* bind new function to Ctrl+r:

    function fish_user_key_bindings
        bind \cr percol_select_history
    end
... and you'll have a searchable history list. To me, together with fish's command completion, it's more powerful than ctrl+r in bash/zsh.


Someone's gotta explain to me how and why oh-my-zsh is slow. I've never once experienced it being slow for me. In fact, I switched to prezto and it was unbelievably slow. I switched back to oh-my-zsh. Maybe I'm just not using it right...


OMZ got painfully slow for me when I used it with a lot of plugins and it was iterating over a lot of different file paths. It seems like ZSH has an issue when you're loading a mass amount of files...or maybe it's just the way OMZ is loading them?


Are you on a mac by chance? I ran into a really weird problem on OSX, still happens as of the latest Yosemite beta, where if you have a lot of system logs laying around, the shell takes an inordinately long time to start (10+ seconds) and do autocompletes.

If you clear out your logfiles by trashing /private/var/log/asl/*.asl, there's a pretty decent speedup.


A permanent fix for this is to create a file called .hushlogin in your home directory. I do it on all my machines.


That totally works - thanks for the hint!

Do you have any insight as to why this happens? It smells like some kind of log parsing to present messages on login, but I've never received any such messages, and a quick vgrep of the various profile/rc's never turned anything up.


ZSH only gets slow because of the customizations, which would be true in Bash as well. Both shells are relatively comparable, though there are still a few things you can do in ZSH that you can't do in Bash. If you keep your customizations relatively light-weight and don't iterate over too many files on each login session, you'll probably be OK.

I wrote a framework to help deal with the shell a little bit after getting fed up with OMZ's slowness: https://github.com/tubbo/homer


> I'm used to typing '\', and that's not possible with fish. Additionally, to get one backslash in any sort of regex (sed, grep), you need four backslashes.

This is a piece of technology we used to have and then somehow lost. Common Lisp uses ~ as the control character for format strings. C uses \ as the control charcter for raw strings, and % as the control character for format strings. HTML uses &. But regexps use \. JSON uses \. And JSON is a new format! \ was literally the worst possible choice. As soon as you have multiple formats sharing a control character, you start to need huge power-of-two runs of it in order to say what you mean.

Who thought it was a good idea to reuse control characters? \ is used in raw string definitions. It should not be used in any other format, if strings might be used to invoke that format. This is a clear case where every standard doing its own unique thing is the correct approach, but we seem to be moving in the other direction.


I run zsh barebones, and I've never been able to get some tab completions to work on bash as well as in zsh. But it's probably possible.

E.g. on some patterns involving *. Care to share your setup?


No, my bash is mostly the default that Debian provides (only semi-relevant option I have enabled is globstar, which is just the recursive globbing). I guess I didn't mean that zsh wasn't that much better, just that I didn't think it was that much better.

I may switch to zsh eventually, but I just switched shells and I don't really want to do it again very soon.


Debian uses dash actually, not bash. I rather prefer it that way since dash is strictly POSIX compliant. Takes some of the tediousness out of creating portable shell scripts.


/bin/sh on debian is dash, but the default interactive shell is still bash (sorry for nitpicking).


Debian uses dash as /bin/sh, but newly-created accounts default to /bin/bash as their login shell.


I really miss Control+R when I use fish. I also prefer to click Control+R again instead of using the inconvenient up arrow key to search the history.


> Goes without saying, but bash-completion. Fish's completion is mostly history-based, which is great for repeatedly running the same command, but terrible for discoverability

Fish has both kinds of completion. You can hit tab to get a list of possible completions (command-list based) if there is more than one, if there is only one possible command it will tab-complete. You can also customize this list.


It does, but bash-completion has a long list of supported commands. Not just git, but also modprobe, pygmentize, youtube-dl, even grub…


You can add/write your own completions for fish http://fishshell.com/docs/current/index.html#completion


> I had to switch away from fish as well because of its lack of vi bindings.

No you didn't. I use vim and fish just fine. Just put this in your .vimrc:

  set shell=/bin/bash


Fish is great. For those wondering what advantages is has over zsh+ohmyzsh, I can say is that by default it provides most the functionality you want without having to install/tweak anything. Git support is built in (you get a nice git prompt) there's syntax highlighting, amazing history completion, predictive commands, man page completions... and so on. To try it on linux, just install fish and then run "fish", to get back to to bash/zsh just "exit"

Only problem is it's not POSIX so there is some weirdness in command substitution, logical operators and stuff. So you still script in sh.


That was precisely my first question, so thanks for the answer, but I don't really see how that's enough to switch… I've been using this "cleaned up/opinionated" fork 'Prezto' for a while now: https://github.com/sorin-ionescu/prezto

If I'm motivated enough to download and install a shell, why wouldn't I just clone Prezto and change one config file to turn on syntax highlighting and git support? Especially when it doesn't bring any "weirdness in command substitution" and I get the great zsh expansions and completions?

Anyways, I'll try it out (why not?) but the benefit to me wasn't clear from the page, and even with your direct clarification here I'm seeing more downsides than zsh + Prezto and not a significant upside.


It's been many years since I've use zsh, so I won't pretend to know what's state of the art with it. I will say that one of the reasons I use fish is it's incredibly easy to customize. My old bash config just came along with me from years of use. Some of it I understood, some of it was just culled from the Internet and kept working, so I kept around (see: prompt customization). But, other than simple aliases, env var setting, and the occasional function, I didn't bother much with shell customization. I find fish simple enough that I can write a new function or tab completion and not have to spend a day figuring out the bash syntax again.

Writing tab completions in fish is really, really simple. It's the thing that initially sold me and it's kept me hooked.

The history is more powerful than bash, too. Although I find it sometimes works against me. E.g., since it tries to guess your command, things you type in lowercase suddenly turn to uppercase until you manage to disambiguate from a previous command.

If you're looking for plugins, there's oh-my-fish [1]. Years back, the term "fish-nuggets" was popular and you'll find repos named that on GitHub with other configuration. I use a couple plugins, but for the most part I don't need them. I think part of that is because fish is featureful out of the box and part of it is because customizing is so easy. I'll usually just add what I need myself rather than trying to find a general purpose plugin.

Anyway, not a direct answer to your question -- apologies for that. Hopefully something in there is of use for you, however.

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


As someone who spends half of my workday in a shell, but doesn't often _code_ in shell, I find "it's not POSIX" to be the advantage.

Loop constructs and defining temporary functions in particular seem much more natural to my brain.

I used it as my main shell for about two years (on OSX even), but had to give it up due to a broken command-not-found handler (long story, but increased my quality of life with non-global bundler so much I went back to zsh).


> Only problem is it's not POSIX so there is some weirdness in command substitution, logical operators and stuff. So you still script in sh.

Yeah some wild-card matching stuff doesn't work, also for example expanding `pkg-config --cflags gobject-2.0` as one would in bash requires calling eval gcc.

On the other-hand it's not like Bash doesn't have weird gotcha's -- for example does anyone remember which of these is a valid conditional?

  string='Foo Bar';
  if [[ *"Foo"* == $string ]]
  if [[ $string == *"Foo"* ]]


I'm never sure when these plugs become too much, but...

I created a language called bish that allows you to write your shell scripts in a sane and comfortable syntax. No more remembering which one of those conditionals to use! Bish compiles to bash, so you also get to keep all of the portability that comes with bash scripts. I haven't had much time to work on it recently, and it's still missing some features, but it's ready to use now:

https://github.com/tdenniston/bish


> I'm never sure when these plugs become too much, but...

Long ago. IIRC this is the thing that translates something looking sort of like a subset of (Python? Haskell? C? I can't remember which.) into mostly-working Bash. It's a terrible idea.


Hyperpolyglot has a nice breakdown of the differences between bash, zsh, and fish.

http://hyperpolyglot.org/unix-shells


Hyperpolyglot's typography, colors, layout and simplicity are beautiful.


Nice link.


I do quite a bit of programming in bash. One construct in bash is absolutely super: process substitution. You can read the output of a program as if it were a file with the construct: <(myprogram).

Bash is a fine tool, but it has a number of flaws that prevent me from using it for certain tasks.

* Functions can only return a status number. Functions are always subshells.

* The hashtable (associative array) syntax is unpalatable, unreadable, and a real abomination. I simply don't use it, because it gives me a headache.

* I can never remember the horrible syntax for most string functions.

* You cannot reasonably store an arbitrary json structure in memory. Embedded lists and hashtables are absolutely unwieldy.

* Bash has no concept of FFI (Foreign-function interface). So, you cannot load an external library and invoke functions it it.

These problems are not particularly impossible to solve, but the Bash authors will probably never do it. Therefore, the final reproach against bash is that they do not publish their source code in an environment similar to github, where users can file their issues and improvement requests. In other words, the bash authors are not in communion with their users.

In what way can the fish shell address these problems?


> One construct in bash is absolutely super: process substitution. You can read the output of a program as if it were a file with the construct: <(myprogram)

Actually had to look that one up[1] -- unfortunately you're right, it's not posix (I don't think I would've tried it in a [ed: non-interactive] script, but I agree it is very nice).

I wonder if you could make a function as a work-around, something like:

    r() {
      #r(first some args <(second other args))
      # Use a fifo:
      ff=$(mktemp fifo)

      # might as well use that for parsing the commands...
      echo "$*" > $ff
      first=`sed -re 's/\((.*) <\(.*/\1/p' < ${ff}`
      echo "$*" > $ff
      second=`sed -re 's/\(.* <\((.*)\)/\1/p' < ${ff}`
      ${second} > $ff &
      ${first} < $ff
    }
      
Adjust for parsing the direction of the <() vs >() etc... Not particularly robust, and the above is un-tested... Just an idea.

I'm not convinced trying to parse shell command lines for macro functionality is a good idea in general...

[1] http://mywiki.wooledge.org/Bashism


Apparantly it's built-in as psub for the <() case (I was looking for the same thing https://news.ycombinator.com/item?id=9569730 ), not sure about >()


Indeed. Came across this:

http://arstechnica.com/information-technology/2005/12/linux-...

I hadn't really thought about that echo'ing the filename might be useful, but this is pretty equivalent to how things work in bash -- with "diff <(some) <(other)", diff gets two temporary file-handles to two fifos -- that are later cleaned up by the shell. As most good ideas, obvious when you think about it :-)


> * Functions can only return a status number.

[In Bourne shell] A function can just print to stdout, and the caller can capture it. In this way, a function has two outputs: an exit status, and a (normally text) result.

It's unusual to go any further, but if you really wanted to you could make a function return any number of outputs by writing to different file descriptors and having the caller capture them all separately.


Fish not being bash compliant was a deal breaker for me.

I use zsh with https://github.com/zsh-users/zsh-syntax-highlighting zsh fish like syntax hilighting and am much more happy.


> Fish not being bash compliant was a deal breaker for me.

Would you mind elaborating here? I'm very honestly curious how the deal gets broken for you.

To explain my curiosity, I've long since come to the opinion that we're in the midst of a long, somewhat painful split caused by a design dissonance over improving the interactive shell UX versus creating a better environment for scripting.

We've been building alternatives around the scripting problem for ages now, perhaps most notably starting with Perl's ascendance. That legacy continues with Python, Ruby, and now many other tools. I'll still reach for bash/zsh as a scripting tool, but only when the situation absolutely will not admit an extra dependency. In my experience, the pain factor goes up far more quickly with code complexity when it's all just gotta be done in POSIX/bash land.

As for the interactive shell UX, fish is notable for simply putting its foot down and just saying "no" to the scripting side. It pushes out POSIX scripting compatibility as an external feature. Calling bash is now on the same level as calling out to {Perl, et. al.}. Whether or not fish is your cup of tea, it's inspired a bunch of competing work in the traditional interactive shells.

At the current time, the above efforts are simply going in different directions. We have numerous better options for rich automation than POSIX shell scripting. Likewise, shell scripting just gets in the way of creating better, extensible developer/admin CLI environments. It has too many quirks (hi, quoting hell!) and limitations (real data structures, please) to work well for an extensibility platform.


When used as a login shell, shell is expected to source some init scripts to fix PATH, locale and stuff; if a particular distro is not written with alternative shells in mind this will fail, esentially making you use two shells which is cumbersome enough to be a deal breaker.


Thanks for the input; that's a good point. For my part, I don't tend to run into this, as I either run a stock distro shell or I go all the way and install the half-sentient metavirus that's my homedir repo. Which I've taught to deal with such vagaries rather efficiently over the years.


The problem is that bash syntax for anything beyond the basics is awful and error prone. It's really hard to make significant progress while still being bash compliant.


I don't know specifically what you're referring to, but zsh has a bunch of extensions to bash syntax (or rather, takes advantage of a lot of "empty space" in the language) which make it possible to just ignore the bashisms and use more sane features when scripting specifically for zsh, while still being able to trivially convert scripts with most bashisms.


Fish is optimized for interactive (the i in "fish") use. Not exactly the same as bash-compliance, but if you have bash-based tools (like virtualenv but without counterpart in fish land), check out https://github.com/edc/bass. Bass allows you to use a bash tool in fish, by running the tool in bash and transporting changes in environment variables back to fish shell.


Same for me... When I saw that I was going to lose all my scripts in .bash_profile and .bashrc that was a no-no. I've got plenty of custom stuff there, so instead I just installed fish completion and several of its functionalities in oh-my-zsh and... ready to go!


Fish is great. I've been using it for close to 3 months now, was using zsh with prezto before.

I find Fish to be simpler to use and more powerful by default. You can probably have a zsh or maybe even bash setup which does the same fish does, but I don't want to do that.


Would you mind expanding on what fish does out-of-the-box that prezto neglects or hides behind configuration? I am in a similar boat as you and was just wondering what I had to look forward to as a prezto user.


Well for example, with prezto I wasn't really happy with any prompt provided, so I decided to make my own, and although it's not rocket science, it's definitely easier to customize your prompt using Fish.

Another thing is writing scripts and completions functions with fish, it's a way better experience than zsh. Writing completion stuff using zsh is really painful.

The preview with the autocompletion is really cool, but maybe you can have that with zsh too.

And then there's the speed, it's totally not objective but IIRC my prezto setup was quite a bit slower.

In the end I just really appreciate that I don't have to spend time customizing my shell: now I install fish on my VMs or servers, and everything is like I want it without me doing anything.

If you're happily using prezto you may not have much to gain from using fish, and you may not even like it since there's stuff from prezto you won't find out of the box.


The biggest thing that swayed me to stick with (and optimize/customize) Prezto was the fact that most of the systems I work with have zsh, or a relatively modern version of it available in repos. Can't say the same for fish.


If you don't mind adding external repositories, you can get up to date versions of fish for most distros.

http://fishshell.com/#get_fish_linux


More a question of corporate best practices than minding, but I appreciate the link!


Hrmmmm good point. Not one that applies to me particularly since if I'm on a server then I'm usually only running pre-written .sh scripts.

(edit: this was a reply to the post below.. not sure how I messed that up.. gah.. such a noob)


I've been using fish for a few months now (switched from zsh). Really nice to have good defaults and minimal configuration, and the suggestions based on previously entered commands are great.

The main issues I have compared to zsh are:

- No bracketed paste mode. If I select multiple lines of text and middle-click-paste into zsh, it adds the whole lot as a multi-line input and lets me review the commands before pressing Return. fish just starts blindly executing them, which can cause accidents.

- Chaining commands is harder. In zsh `foo |& less` pipes stdout and stderr. Also, fish's `foo; and bar` is longer than `foo && bar`.

- Hashes in words start a comment in fish. e.g. `opam pin repo#branch` is treated as `opam pin repo`, pinning the wrong branch. zsh only treats # as a comment at the start of a new word.

- While completion history and `set -U` are really useful, it sometimes forgets everything and I have to start again, which is quite annoying.

On the whole, very happy with it though!


Since Apple seems forever stuck on an ancient Bash version (due to GPL 3, I believe), I keep hoping they switch to Fish (or a home built solution, à la Swift, which could be interesting) with every OS release.


Fish does feel very Appley to me. I wouldn’t be surprised.


Well, "ridiculous_fish", the guy who sort of revived the fish shell is an engineer on the AppKit team at Apple: http://ridiculousfish.com

I remember installing and using fish 4 or 5 years ago; it was not a great experience -- but after he "took over", I switched and couldn't be happier with fish.


Interesting! My impression was that Apple engineers were prohibited from building anything outside of work.


According to Wikipedia[0], fish was originally created by Axel Liljencrantz in 2005. The commit history from GitHub does go back that far (I imagine it was imported somehow), so I assume it's complete. The first commit from ridiculous_fish is in 2011.

So if there is such a policy at Apple, I would expect that it doesn't prohibit contributing to already-public projects.

[0] http://en.wikipedia.org/wiki/Friendly_interactive_shell


That makes sense, the create of fish works at Apple: http://ridiculousfish.com/blog/about.html


For those who like the autosuggestion feature of Fish but can't leave oh-my-zsh, there's a plugin for that: https://github.com/tarruda/zsh-autosuggestions


For those who use antigen you can add this line to your .zshrc to install this.

antigen bundle tarruda/zsh-autosuggestions


I can clearly see the difference between Fish and regular ol' bash, but struggling to see what value Fish adds above prezto/zsh. Could anyone help me out here?


Fish breaks compatibility with traditional shell languages. The syntax is a bit different, the variable expansion rules are a bit different, etc. It also gets rid of a bunch of features and configuration options, such history expansion ("$!!").

The positive side of this is that fish is very simple and has a very pleasant experience out of the box. And this is not just about having "good defaults" - its also about having a good design that encourages having one way to do things. That said, an interactive shell is a very personal thing. The only way to really get a good feeling is to install and check it out.


I used Fish for about of year. But I ended up recently switching back to zsh. Stock Fish is far more useful than stock zsh. However, the community around zsh is far more active and I found that most of the functionality that Fish contains and zsh lacks that there are plugins to achieve the same effects.

I'd encourage you to check it out. The scripting language in Fish is the best I've ever used for a shell. But it's also incompatible with Bash/zsh.


> what value Fish adds above prezto/zsh. Could anyone help me out here?

- not assuming you're using an outdated terminal so doesn't waste a column when using a right-hand prompt?

- lots of async calls, thus really fast.


I've used fish shell for about a year and I love it. I recently stumbled upon the design document, which summarizes well why I like it so much: http://fishshell.com/docs/2.0/design.html

I actually think that design document could be a good start for a lot of projects.


Yay, I am specifically waiting for "New `fish_preexec` and `fish_postexec` events are fired before and after job execution respectively" [0] It allows to implement something like undistract-me [1] for fish.

[0] https://github.com/fish-shell/fish-shell/issues/1549 [1] http://mumak.net/undistract-me/

edit: Just installed the beta and implemented it (status WorksForMe) https://github.com/qznc/dot/commit/8cf55564383ed93af148234d2...


>Sane Scripting -- fish is fully scriptable, and its syntax is simple, clean, and consistent. You'll never write esac again.

I can already do sane scripting, with Python. I suspect that as soon as I try to to anything slightly complicated, Python leaves fish scripting behind.


Fish is definitely good, but not great enough to justify a switch from Bash. I maintain tens of thousands of lines of Bash scripts and was considering switching to Fish once, but decided it wasn't worth it.

When you compare the *nix shells to PowerShell, they feel prehistoric. We all use grep, sed, awk, and the likes, but don't you get tired of having to deal with unstructured data and gross limitations of the shell like basic data structures. Yes, the purpose of the shell is to be quick and dirty, but it doesn't take that much to add some programming sanity and some standards for structured data! There's a port of PowerShell to Mono, Pash [0], but it's so heavy in terms of requirements and has somewhat unclear future. Of course, there's also Xonsh [1] and Xiki [2], but they are pretty new.

[0] https://pash-project.github.io/

[1] http://xonsh.org/

[2] http://xiki.org/

P.S. One of my favorite Fish feature is Event Handling [3].

[3] http://fishshell.com/docs/current/#event


I've tried to use and get comfortable with Powershell but it's insistence on types and overly heavy syntax just get in the way for my primary use case for shell scripting. (e.g. quick and dirty hacks)

I don't in fact get tired of unstructured data and the limitations of the shell like basic data structures because nine times out of 10 the data I have to work with in a shell is exactly that. Unstructured and basic. Not because of the shell but because the source of that data provides it that way.

Powershell with it's intense focus on fancy datastructures makes something like

    sed '/foo/d'
unecessarily hard and that's exactly the sort of thing I use my shell for.

If I want something more powerful for working with structured data I'll use Python or Julia.


PS> echo foo,bar,baz | ? { $_ -ne "foo" }

The sed command is not a shell. You can use sed in PowerShell.


Yeah but sed isn't present by default in Powershell. in Unix systems it is and Powershell's ecosystem makes the approach sed uses a second class citizen.


Using fish doesn't mean you have to stop using existing bash scripts.


I understand that, but my point was that Fish is yet another big missed opportunity.


I'm still not certain what you are missing from it? It's not perfect but good enough for an interactive shell at this point. Good to stick to .sh for deployed simple scripts on 'nix though.

Fish won't become PowerShell, that's for sure. I like the idea of PowerShell, but it's a bit too ugly in person. I'm happy enough with cmd, cmder, and Python for scripting.


Powershell focuses a lot on being a good language to write scripts on. Hence the data structures, verbose names, etc.

On the other hand, Fish is mostly focused on being a powerful interactive shell. Its all about having good auto completion (fueled by parsing manpages), history search, etc.

I do believe that its very hard to have a shell language thats good at these two domains at the same time and that we are better off having separate languages for each. Trying to solve both these problems at once is what made bash into the mess it is now in the first place.


Fish (like zsh) may leave a lot to be desired, but it is an enormous improvement over bash. I have been using fish for several years, and especially its autocompletion is indispensable to me. (However, I use it as an interactive shell only; TCL is my scripting language of choice.)


Is there a simple, sane introduction to PowerShell? I've read through a dozen PowerShell scripts in the last week and find them incomprehensible compared to Bash scripts.

I know I learned Bash 15 years ago, but it's not just familiarity that's causing the confusion



Seems like their slogan might be a little limiting.

> fish is a smart and user-friendly command line shell for OS X, Linux, and the rest of the family.

I'd wager majority of OSX users are not going to be changing shells, but by specifically enumerating OSX as the first example use, it feels like the others are mere afterthoughts.

Would be better put:

> fish is a smart and user-friendly command line shell for the entire *nix family.


While that wording is more precise, the current wording is better for promoting the software. Ordering by market share makes sense, and users who are quickly scanning the page for compatability information don't need to make the connection between OS X or Linux and *nix, and can instead recognize their current system easily.

If this were documentation the change should be made, but it's probably not the right move on a website focused on promotion.


The lead developer is on the Apple AppKit team.


I tried really hard to use Fish for awhile and if the shell was just history, completion and sane defaults (and it is for some people) it would have a very good case. But not being even remotely compatible with bash drove me nuts as the shell is my REPL.


Is there a way to use this in the excellent Git Bash for Windows? Because Git Bash is amazing and I don't see myself going back to cygwin anytime soon. I understand how they could be very incompatible because of the way Git Bash is built.


I've been using fish for at least a year now and I absolutely love it, altogether with oh-my-fish [0].

I don't mind the incompatibility to bash, but using "; and" instead of "&&" is a little annoying.

Everything else is great.

It actually auto-completes remote hosts and paths when you type ssh or scp commands! It also fuzzy-completes filenames when you're lazy (or have typos in them) and a bunch of other neat things.

The up-key function after typing in parts of a command and ^F have probably saved me hours of time wasted in bash.

0: https://github.com/bpinto/oh-my-fish


3 years using Fish shell now, and wouldn't go back to anything else. The autocompletion (including fuzzy matching) feature is just so vastly better than in other shells.

I must say I am not a huge shell wizard and use only a handful of custom functions, but I've found shell to be very pleasant to work with and would recommend it to any web developer who doesn't get "dirty" with shell scripting a lot.

The only problem I had was that I had to explicitly set the shell used by vim in order to make vim plugins / configs work properly by using this line:

set shell=/bin/bash


I've been a Linux command line (bash) user for 20+ years now and I must say, I would really consider switching to this. I haven't even started to dig into the features yet, but the filename and parameter completion alone is enough to stop me from pulling my hair out.

Filenames are getting very long w/ so many special characters, this is great. I also like the idea of having a web based config. I really won't miss wrestling with bashrc and bashconfig in vi. Definitely will try this.


I've been using Unix (and mainly Linux) for 20+ years as well. First using bash, then zsh the last couple of years and I recently switched to fish. The switch was fairly effortless and it took maybe 2 days to not even notice the differences anymore. I do have to look up some things now and then but overall it has been an improvement.

What I like about fish shell is the same why I use the i3 tiling window manager. It has sane defaults and it clicks with how expect things to work, how I would design them. Sane defaults mean a minimal config file so it's easy to look up problems and change things.

I'd at least try it out if I were you.


how long have you been using the i3 tiling window manager?


Fish and zsh grew out of bash, which again was a free replacement of Bourne Shell — but from Bourne Shell there was another interesting development, namely rc[0]. rc was developed at Bell Labs as the successor of Bourne shell. I usually prefer its syntax to the bash derivatives when scripting. It has a much cleaner feel to it.

[0] http://plan9.bell-labs.com/sys/doc/rc.html


I'll switch to one of these new-fangled shells if I ever master bash.

In any case, bash -- in one of its many forms, colors, and sizes -- is what I usually find myself in front of.


Their shitty webpage still requires javascript, though!


and this is 2015, why are people still against JS?


Because it's bad practice to demand people use it when it's not required.


Um, pretty sure they can make whatever demands they want on their own website.

JS is standard issue in 2015, come on out of the bunker.


If they can't write a page without useless frills, they can't write a shell without useless frills.

Useless frills are buggy and slow.


Pretty flashy :-) I like how it told me to use () when I tried typing $(), and the autocompletion is quite impressive.

However, how do you work around the lack of <() and >()? E.g. if I want to do the equivalent of

    $ diff <(xzcat foo.xz) <(xzcat bar.xz)
?

EDIT: nevermind, I see the fish version is

    $ diff (xzcat foo.xz|psub) (xzcat bar.xz|psub)
which actually does the mkfifo dance for you :-)


I used fish for at least a year, maybe more. I eventually switched away to zsh. Whichever theme I used, rendering the status of git repos took ages, and the breaks from Bash syntax were just a bit too much.

I loved the overall friendliness though, it was a genuine pleasure to use for the most part. I hope to use it as my default shell again some time in the future.


> Whichever theme I used, rendering the status of git repos took ages I don't think this is fish's issue. In fact, this will happen in any shell (bash / zsh) if your git repo is big. The solution is either (0) speed up `git status`-like commands by enable git cache, or (1) use async showing git repo status just like prezto.


Would you mind elaborating a bit? When I switched to zsh I started with oh-my-zsh but soon uninstalled it as it was too much for my needs. I started again with simple .zshrc file and I'm hesitant to going back to frameworks like prezto but working on a really big project in git slows down zsh noticeably.


The autosuggestions looked pretty sweet! Here's something that enables similar functionality in zsh: https://github.com/tarruda/zsh-autosuggestions



https://github.com/qznc/dot/blob/master/config/fish/config.f...

I use something similar: tux instead of frogs and a personal fortunes file. Mine also prints the current date, hostname and uptime.


Nice! I've actually adopted a minimal approach as of late: https://gist.github.com/montanaflynn/da1f0565c95a5a37b458


I don't get the logic behind a shell initialization file that tries to 'apt-get install' anything.


Looks interesting and great timing. I got super annoyed today when I saw that the latest version of gnome terminal in Ubuntu stopped supporting changing tab titles via the GUI.


The shell is completely independent of the terminal emulator. Fish is the former, while you're complaining about an example of the latter. (My recommendation for a terminal emulator would be urxvt with the tabbedex extension. YMMV.)


I have seen many people recommending urxvt. What is the advantage of it compared to gnome-terminal ? The last time I tried it, it's default font size was too small and I didn't like the font. Does it take some fiddling (configuration etc) with urxvt to bring it a minimal usable state ?


> Does it take some fiddling (configuration etc) with urxvt to bring it a minimal usable state

Yes. urxvt is pretty minimal and will likely be rather ugly by default. However, you can customize pretty much everything via editing your Xresources file.

In terms of advantages over gnome-terminal... it's lighter weight and considerably faster (though tbh, speed isn't that important for most people). It doesn't depend on any Gnome services/libraries, so it integrates better with e.g. a tiling WM. It's stable, in the sense of the developers won't cut <insert feature> out. The configuration is very flexible and it's extensible.

However, to be honest it's not for everybody. I wouldn't even say it's for "power users", it's really mostly for minimalists and the default configuration is incredibly sparse. If you're dissatisfied with gnome-terminal, I'd probably recommend roxterm or lxterminal instead. IMO, urxvt is more one of those "I already know I want it and I know why I want it" kind of things. That said, I've been using it for a few years and I really like it.


So far, gnome-terminal is the only one* I've seen that can rewrap text properly when the window width changes. Does urxvt do that? Is there something lighter (than gnome-terminal) that does?

* not the only one, but I'm not sure finalterm is really ready to use yet, and it's certainly not lightweight.


I just checked, and it seems to support rewrapping without any trouble. (Though, oddly enough, GNOME Terminal 2.31 doesn't.)


I'm on 3.14. Thank you, I will probably like that much better.

Edit: Hmm, it doesn't seem to work properly in 9.20. Well, I should probably be using tmux anyway, which does fix the problem.


I would describe it as the simplest fastest least buggy terminal available that supports tabs and unicode. So I have tabs for each machine and tmux sessions on each of those machines, kind of 2-dimensional. As you'd guess for something with a full name of "unicode-rxvt" the unicode support is bulletproof, perhaps the best out there of all possible terminals although it varies over time.

As simple as possible, and no simpler.

It does nothing that impresses other terminal authors. Other terminal authors seem to prioritize user experience beneath keeping up with the achievements of other terminal authors. So it is completely incapable of 3-d widget animations, or transparent viewing of 3-d accelerated VDPAU movie rendering via transparency, or any number of things that are extremely technically challenging and "desktoppy" and very impressive to other terminal authors but users primarily see as something that makes it slow and crash alot and complicated and distracting.


I think it does. It starts off about as basic like xterm (i.e. using "fixed" as the font), so it's really low on resources. It is missing a bunch of features out of the box (Ctrl+Shift+V to paste, quick adjustment of font size at runtime, URL clicking, drag-and-drop, tabs, ...), but it has support for plugins (written in Perl), which is its other major advantage (all of the missing features I've mentioned have been implemented as plugins).

To quickly try it with a larger font size, you can do urxvt -fn 'xft:Dejavu Sans Mono:size=10' (but it's usually configured through X resources, see the urxvt man page)


What does guake count as, then?


Guake is just a Quake-style terminal emulator. Under the hood it's basically gnome-terminal (it uses the VTE libraries).


a terminal emulator. From the guake project page[0]

  Guake is a dropdown terminal made for the GNOME desktop environment
[0] https://github.com/Guake/guake


For crying out loud... another instance of the GNOME team's insistence that they know better than their users, no doubt.


Best i can tell, Gnome has lost respect for their users ever since they started doing usability testing for their interface.

This because they consider any usage that deviate from their planning a indication that the user is an idiot...


I was just thinking about how no one even pretends GNOME Shell is a serious contender any more. Sad that they've squandered their installed base so thoroughly.


Been using Linux since 1998. GNOME 3 and GNOME Shell have been my favorite DE since then.


I use gnome shell. What should I switch to that, and why?


xfce4-terminal is a good choice. I like that it has an additional feature to gnome-term, in that it can highlight the text of a tab when it outputs text. It is nice that you'll know when to check up on long-running tasks.

https://en.wikipedia.org/wiki/Terminal_%28Xfce%29


Been using it for almost two years I guess. Find it really nice. Would one day love to be more able to script with it; adding more features for my own needs.

Give it a try at least :-)


2.2 beta 1 was released last week. Testers welcome!


Has the bug with removing autoloaded functions been fixed yet?


If you mean the fact that a removed autoloader function may be autoloaded again, then yup, that's fixed in 2.2. Here's the issue that tracked it: https://github.com/fish-shell/fish-shell/issues/213


When is 2.2 planned?


Comes around once in awhile.

It's good, but quite a few things are incompatible from what I remember after trying it a year ago.


How does this compare with zsh + ohmyzsh?


Much faster, but much less configurable. If you have a decent config on ohmyzsh already, and it doesn't take too long to start up (you have an SSD), there is little point in switching to fish IMO. Especially if you use a lot of these things: https://github.com/fish-shell/fish-shell/issues?q=is%3Aissue...


I've been using fish for a while, but generally don't go crazy customizing my shell. What makes it less configurable? It'd be helpful to know what pitfalls to avoid.


And their webpage is broken


You should have called it the clamshell.




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

Search: