Ok I’ll bite
What are the differences/benefits of one over the other?
Ok I’ll bite
What are the differences/benefits of one over the other?
First, I’m using “vanilla”
zsh rather than
oh-my-zsh (which is a config framework, similar to what spacemacs is for emacs).
The main reason I did the switch years ago, was because of the much better tab-completion experience that oh-my-zsh provided (back then I used it).
Also it had the double glob for recursing directories (
**/*.ex) which did not work for bash back then and today is only available after explicitely configuring it.
Another problem that I often had with bash and globbing was that I hit the “max command length limit”-wall, since some globs easily created commands much longer than 10k characters, and I do not even know how small the limit is or if one could change it, but I never hit this limit with
Last but not least, in theory, I could filter globs in
zsh by file age, size, folder or file or sym link or whatever… Without the need to use
find, but I rarely use those extended globs, as I can not remember their syntax and therefore have to look them up everytime.
In theory, it could live update its prompt and show a live clock at the current prompt.
As I am using vanilla today I have to manually keep my plugins up to date, but that is not a problem.
My most loved plugins are zsh-completions and zsh-syntax-highlighting which syntax-colors the prompt on the fly. This is a nice thing when often dealing with constructs that are a bit more involved than just a copy or deletion.
My third most plugin is not an argument for zsh, since there are powerline themes for bash as well
Sorry, I choose neither. For many years I tweaked my ZSH configuration and carried around a theme file. Eventually I decided to try Fish and was delighted to find it did everything I had configured ZSH to do right out of the box:
The only thing I have done to configure it is tweaking my prompt slightly.
The only two downsides I have encountered:
envto set some variables.
fish every now and then, but it has two major downsides for me:
aliashandling is below par. Sometimes I need to look up what an alias would expand to, I can’t do that with
For me fish is entirely for command line usage where the most complex thing I’ll script is a small loop. I still write all of my scripts to be portable, either in sh or bash if I can get away with it.
It has been difficult to convert most engineers I work with as well. The minor inconvenience of not being able to paste something from a README or SO is enough to throw away the day-to-day efficiency gains.
I can extend
zsh to give me what I miss from
fish, but I can’t add proper
alias handling to
fish, there is no loss for me.
PS: you shouldn’t ask such kind of questions you could have asked whether to use
vim as well Such questions tend to get answered with a grain of religious beliefs
I can’t live without the per-directory-history plugin that comes with oh-my-zsh.
What @sorentwo says.
I switched from Bash straight to Fish and it nicely works out of the box (although I admit that I use oh-my-fish and fisher as plugin/config managers for themes and prompts).
But I agree with @NobbZ, too. It’s really annoying that the syntax is so different from bash.
Lots of times I got tripped up by this.
But it’s still a really nice experience because I most use it for standard command line stuff where the commands are the same in bash and in fish.
Indeed! I just use the default which comes with the distrib I installed, and thus bash. For anything more complicated than piped command lines I use python anyway, which preserves my sanity.
I do not get what is the problem there,
type my_alias prints generated function without any issues.
POSIX shell, there is no such thing as “regular shell” as there is a lot of different shells (csh for example that has enormous influence on other shells, including
Not in Fish 3.0 as they have added support for
|| so almost all snippets works without any problems.
My biggest problems with Fish shell (which I am heavy user for about 6 years) are:
source (foo | psub)that will source output of
foocommand (in Bash it is
source <(foo), but I cannot do something like
foo | tee >(foo)(Bash syntax) right now. This is sometimes problematic as I need to fallback to tools like
peefor that (ex. I have script
ixthat uploades provided file to the ix.io service, and it would be really useful to print resulting URL to the shell as well as copying it to the clipboard, unfortunately it is not possible in easy way.
function tak; yes tak; endand I will try to run it in the pipe, like
tak | teethen it will not output anything until I kill everything. It is problematic, as I cannot write file watcher function.
And I assume you will get more auto completion in zsh/bash vs fish.
For example k8s
Enabling shell autocompletion (Bash on linux, Bash on Mac, Zsh) but no Fish
But any way I would stay with Fish
Whoa, so it’s impossible to do something simple like print status updates or a progress bar?! o.O
/me is a ZSH user
zshs behaviour with what I get from
zsh $ alias ll ll='ls -ah` fish $ type ll # Defined in /usr/share/fish/functions/ll.fish @ line 4 function ll --description 'List contents of directory using long format' ls -lh $argv end
In ZSH its so much easier to see what the alias actually is. Also I can make a distiction between an
alias and a
That is the main difference, in ZSH you have aliases and in Fish there are only functions, and
alias is also a function that defines other functions. So unless Fish add some “special handling” for aliases (I do not believe it will as it would be against idea of the Fish) then you will not be able to get the same result as in ZSH. Everything to make shell simpler with less corner cases.
You can print progress, what do not work right now is using Fish’s function to be run as “parallel producer”. I cannot describe it better so maybe you can check this issue.
Ah! You meant multiple inputs to a single output stream/pipe! Yeah that is pretty trivial in bash/zsh/etc, especially via backgrounded processes… That’s supposed to be a standard posix thing that streams can be multiple I/O connectors, so it is exceptionally weird that fish doesn’t follow that… o.O
That first post on that issue was very off the mark, I don’t think it would have anything to do with fish needing to execute its bytecode in parallel, you can easily background ‘other’ processes as well and they should still be attached to the same output pipe. I’m guessing that they are just creating new pipes and listening on them directly instead of passing around the pipe kernel handles as it should be doing?
That’s a very weird to read issue… O.o
Hmm, so it seems they background a process when
& on it but they don’t background their own interpreter when doing the same (or emulate it as all modern shells do), that’s a very bad misdesign there and breaks the standard posix expectations… o.O
EDIT: So what features does fish have that zsh doesn’t via plugins (zsh is by default very simple but very pluggable, far more so than bash)?
Not exactly. Fish do not start subshell on
& and this is the root of the problem while ZSH and Bash does (just run
echo $$; sh -c 'echo $PPID' & to check that out). This simplifies few things, but causes problems like this one.
Well actually ZSH and Bash ‘pretend’ to start subshell’s, but they emulate it only as far as needed to fake it before they eventually end up spawning a real subshell if the need actually arises (surprisingly not very often). It seems that whole faking it step is what Fish is lacking.
I’m also a big fan of fish. I tried zsh numerous times over the years but never felt at home with it. Something about fish just clicked for me, I’m very glad I tried it
I wouldn’t use it for writing scripts, I use
#! /bin/sh for those.
I’ve actually found fish has better auto completion thanks to its parsing of man-pages to determine flags.
Of course this is only possible for software that includes a man page, something which seems to be less popular now…