Please submit the original article. Spamblog submissions are subject to removal, readers are encouraged to report them.

GNU/Linux is a free and open source software operating system for computers. The operating system is a collection of the basic instructions that tell the electronic parts of the computer what to do and how to work. Free, Libre and open source software (FLOSS) means that everyone has the freedom to use it, see how it works, and change it.

GNU/Linux is a collaborative effort between the GNU project, formed in 1983 to develop the GNU operating system and the development team of Linux, a kernel. Initially Linux was intended to develop into an operating system of its own, but these plans were shelved somewhere along the way.

Linux is also used without GNU in embedded systems, mobile phones and appliances, often with BusyBox or other such embedded tools.

zsh is mainly praised for its interactive use, because it is better customizable:

The prompts are more versatile (it can even display a prompt on the left and another on the right) - you can also make a proper vi-mode that displays the mode it is in.

The completion is more customizable and often faster (there is bash-completion that can do per-command completion, but it's often slow)

It's also been said that zsh is faster, though I haven't noticed (apart from completion).

Basically, bash does 90% of what zsh does even for interactive use (especially with bash-completion) and you're gonna have it on your system anyway for scripts (even though zsh is mostly compatible). If that is enough reason for you to use zsh, then go ahead - it's just not a night-and-day difference.

I did this because I didn't want to spend hours configuring zsh, so it got many things set up for me out of the box. The few things I did want to change (mostly visual stuff) were easy enough to manipulate.

I like the management setup better: simlinks into the repo, which can then be pushed to my fork. I'm sure I could set that up with oh-my-zsh so maybe there's not much advantage. Just worked well for me I guess.

The author still responds to pull requests, etc. (within the past few days), so it's not abandoned.

However, "sh" mode should be the same thing in both (everything else is a bug), and a script will be run by the shell specified with the shebang - something with "#!/bin/bash" as the first line will run in bash.

I've written a ~300 line bash script (without thinking about zsh) and could just run it in zsh without running into any bugs.

So: not 100% (which is why you should keep bash installed), but not too bad (like fish, which is almost completely different).

Zsh has much, much better support for arrays in syntax and functions that can use arrays. Zsh even has limited support for set operations. It makes scripting in Zsh oh so much nicer. Zsh doesn't resort to Bash's IFS to make arrays or make strings from arrays, you just split and join like you would in a "real" programming language. The difference is using arrays for very basic operations with a fair amount of boilerplate in bash vs being able to use arrays everywhere with no overhead in Zsh.

From what I understand, Bash doesn't implement true array data structures. Under the hood, they're apparently nothing but a delimited text string or text file. Zsh have true arrays and if that is so, it would mean that the arrays entry pointer is mapped to a memory address and then you perform pointer arithmetic to jump to other array indices. With small data sets, this wouldn't really matter. But if you wan't to load up huge arrays, this would be quite significant.

If this isn't really the case, I would be very glad to learn more about how arrays are implemented in shell scripting.

Each entry in a delimited string may be composed of a variable number of characters relative to other entries. This would preclude, for example, pointer arithmetic to traverse the array, as you could not just add a uniform number to the pointer for each iteration.

There are a couple things that zsh does better than bash (and I never said anything to the contrary), I just fail to see how it's "night-and-day" (and many things zsh fans think are better are also possible in bash, though the configuration is somewhat harder), especially considering that bash is installed everywhere and uses readline which is also used by e.g. mysql and python (which means configuration is shared).

Plus: I've got all of those I want right now with stock zsh (without oh-my-zsh), which I'm just trying out, so what exactly does oh-my-zsh add?

If you read zsh's man page, you may notice that <(...) is another form of process substitution which is similar to =(...). There is an important difference between the two. In the <(...) case, the shell creates a named pipe (FIFO) instead of a file. This is better, since it does not fill up the file system; but it does not work in all cases. In fact, if we had replaced =(...) with <(...) in the examples above, all of them would have stopped working except for fgrep -f <(...). You can not edit a pipe, or open it as a mail folder;

However, vim doesn't have a problem with editing FIFOs, and diff works too.

Having the output each time you cd is annoying, but yeah, does the trick.

What's different here from defining a dir as variable (though global aliases are awesome)?

Look at the prompt; zsh recognizes it's a directory alias and doesn't show the full path.

(Possible in bash with some hackery, but slow AFAIK)

Yes, in fact, you should be using git.git's official prompt which is much more solid, and it works in zsh as well.

This is not unique to zsh in any way, I just thought it was nice to show.

(Partially covered with extglobs)

That's right, partially. They are nowhere near as complete as what zsh has.

How is that different from <()?

That it creates an actual temporary file that you can write to, so you don't get those annoying messages from the editor that you can't.

There are a couple things that zsh does better than bash (and I never said anything to the contrary), I just fail to see how it's "night-and-day"

The completion system alone makes it night-and-day, you are just refusing to see it for what it is.

As a developer for git's completion in bash and zsh, I can tell you that bash's completion is so ridiculously simple it's ridiculous; it's emulated by zsh with a single script that isn't that big. It all boils down to a list of words in the COMPREPLY variable. That's it.

You can't have descriptions, tag grouping, menus, user configuration per tag; hide, make verbose, reorder, replace functions, etc. And subtle behavior like --git-dir= show a list of directories.

You can't even put them in the same weight category.

and many things zsh fans think are better are also possible in bash, though the configuration is somewhat harder

Some, yeah. But many are simply not. The list above already contains plenty that are not possible, and it's not exhaustive at all.

For example, I forgot the shared history: I type a command in one shell, go to another one, press up, and it's there. Impossible in bash.

Look at the prompt; zsh recognizes it's a directory alias and doesn't show the full path.

Oh yeah, didn't see that - it's a minor thing though.

That's right, partially. They are nowhere near as complete as what zsh has.

I edited that after - globstar does the exact example you show (since bash4).

That it creates an actual temporary file that you can write to, so you don't get those annoying messages from the editor that you can't.

(Again, edited) vim can edit a FIFO, it just needs to save somewhere else (and you probably want to choose the filename anyway). Non-interactive commands (like e.g. diff, which I use the most with this) also don't have a problem.

I can tell you that bash's completion is so ridiculously simple it's ridiculous;

Yeah, bash-completion is somewhat hackish. I'm not sure if it could be done better.

For example, I forgot the shared history: I type a command in one shell, go to another one, press up, and it's there. Impossible in bash.

It's not. If you have spent any time analyzing your shell command, you notice that spend a lot of time on certain directories, and it doesn't make sense to show the full path of them.

You don't want you prompt to show '/run/media/felipec/wd', or '/opt/scratchbox/users/felipec/home/felipec', and you don't want the basename either.

It is extremely nice, and the only reason you dismiss the feature, is because you don't have it in bash, and you don't want to feel it's inferior.

I edited that after - globstar does the exact example you show (since bash4).

That's the only one I could think in the couple of seconds I had to show the feature, there's plenty bash cannot do, for example: **/*(om[1]); the most recent file in a directory.

(Again, edited) vim can edit a FIFO, it just needs to save somewhere else (and you probably want to choose the filename anyway). Non-interactive commands (like e.g. diff, which I use the most with this) also don't have a problem.

Of course it can, but you see annoying errors such as:
E211: File "/proc/22906/fd/11" no longer available

Right after running: gvim <(echo foo).

Yeah, bash-completion is somewhat hackish. I'm not sure if it could be done better.

Somewhat? It's a total hack. It couldn't be simpler. It has no features whatsoever.

And of course you are not sure, but I am, all you have to do is look at zsh completion. I would gladly show a completion script a couple of lines long that bash completion could never ever hope to achieve.

Possible, though the history -a call is a hack

That's now what I said. And yet, still a hack.

From where I'm sitting, it's more like death by a thousand papercuts (that may or may not matter to you) than one single thing.

There's thousands of small things, but there are also huge ones, like completion: type 'rsync --<tab>'; bash won't ever reach that level.

I'm trying out zsh right now, but I think that bash does the job too, though you may use your shell more than I do.

What's lacking here is the explanation, and we already talked about that.

I think where we most disagree is in how big of a deal the differences are - I agree that zsh is better than bash, I just think that the difference is not much for my personal use (and probably for a lot of other people as well), especially considering how widespread bash is.

And then simply filter depending on what you have typed. Wow, such sophistication.

What's lacking here is the explanation, and we already talked about that.

Yeah, you want to dismiss possibly the most useful feature any shell could give you by saying "we already talked about that". Yes we did, and it still hasn't stopped from being an incredibly awesome feature bash could never even dream of supporting.

I think where we most disagree is in how big of a deal the differences are - I agree that zsh is better than bash, I just think that the difference is not much for my personal use (and probably for a lot of other people as well), especially considering how widespread bash is.

They don't make much of a difference for your personal use because you personally avoid using them, because they are not in bash.

I once thought 300MB was too much storage, until I actually used it. You never think things you don't use could possibly make such a big difference, until you actually have them, that's human nature.

Start using directory aliases, start using the completion to see argument help, enable the menus and tag group names. Only then will you be able to see how amazing those features are.

Me, I use fish. From what I gather, you need to spend a lot of time to customize the zsh configuration. (On the other hand, it'll do exactly what you want it to do then.) Fish is the opposite: there isn't all that much to configure, things just work out of the box.

The main reason why you'd want either of them is that command autocompletion just works so much better. Don't know how exactly the tar options should look like? Your computer does - and with a good shell, it'll tell you.

It can also do basic syntax highlighting for the things you type into your shell. And it can automatically suggest commands from your history (without a single keystroke).

Hm, I just tried a few only slightly atypical commands with a man-page (cryptsetup, yum, xmonad, bash) and none of them were autocompleted :/ That could be because fish_update_completions doesn't like some non-ascii character in one of the man-pages on my system.

When it has collected some history, it doesn't really matter that much though. It can complete the commands you actually use from there.

Fish is really out there in terms of awesomeness. The multi-line scripting on the shell is really something to behold. My only qualms with it is that it isn't so very customisable. The syntax is other-worldly compared to other shells, though. That could be a problem for some.

It's missing some important language features, such as true sub-shell support. Unfortunately, this has basically made it impossible for me to use it for much of my work. It's really nice though for other reasons.

I would use it all the time if it implemented all the language features in zsh.

I would miss it. It might be archaic, but the funny thing is, I started out using its "replacement", command-line editing, 25 years ago in ksh, before there was such a thing as bash. ksh didn't have the ! history modification stuff (bash got it from csh), so I never learned it. I moved from ksh to bash after about 10 years, and still pretty much stuck to command-line editing. But the past just year or two my use of the bang stuff has gone way up, because it's just so expressive. Things like this let me type without even having to look at the cursor:

"dosomething && doanotherthing" is a actually a pretty bad idea, because "doanotherthing" will not run if "dosomething" returns 0. && is a logical AND, therefore the interpreter already knows the result is 0 if the first part evaluates to 0, and can skip evaluating the second part.

It won't work, but how exactly it will fail depends on how the alias is handled. I know bash will only expand an alias as the first word in a command, so the '!!' would not get expanded and presumably cause a 'command not found' error:

I tried fish. To me, it was the equivalent of Clippy. Sometimes it was helpful, but most of the times it just got in the way because you could never really be certain that what it was showing was accurate.

That, and the fact that it's almost entirely unconfigurable made it unworkable for me.

One disadvantage would be that it's not fully compatible with bash, only mostly, nor is this a goal of the project. But you can stick to bash for scripting, so I don't really see it as that much of a problem.

I am impressed by this but without it showing what the flags actually do this is not that useful. There are like 40 switches that can complete "ssh -". It can be useful for a few things though, like "ssh -O".

I switched from bash to zsh a long time ago. The autocompletion just feels more lively.

However, the one thing that I miss in Zsh is Bash's HISTIGNORE=?:?? option which doesn't include all single and double character commands to the history. Still haven't figured out how to do the same in Zsh

I do find directory tab completion to be much nicer than bash - not having to waste scroll space to see what the next dir has over the current one is a nice advantage. The way bash does it is ugly in comparison.

not having to waste scroll space to see what the next dir has over the current one is a nice advantage.

Yes - when I switched to zsh I didn't even notice this. Then whenever I'd go back to a bash shell this irritated me a lot. Does bash not have an option to enable zsh style behavior with regard to this?

Maybe I'd just need some time to get used to it, but I don't like "intelligent" tab completion. I don't want my shell to have no idea what to do just because a download has the wrong extension. For me a simple completion to all files that match the given name is the least frustrating.

Oh god this annoys me so much. I generally despise all things that try to act like they're intelligent. These new-fangled features bash comes enabled with out-of-the-box nowadays remind me entirely too much of Word's auto-replace and such.

a simple completion to all files that match the given name is the least frustrating.

Oh god this annoys me so much. I generally despise all things that try to act like they're intelligent. These new-fangled features bash comes enabled with out-of-the-box nowadays remind me entirely too much of Word's auto-replace and such.

Well, they can compete by being so awesome its worth swapping to, see: bash vs the shells that came before it.

Zsh is awesome, and it's totally wroth swapping to. And yet they don't. Because they are lazy, because they haven't taken the time to properly evaluate zsh.

Compare it to something like FishShell which I at least see as different enough to be worth talking about,

You are easily impressionable. The default configuration of fish looks nice, but it's nowhere near the point where zsh is with a similar configuration, it's just too buggy. It would take years for Fish to reach the maturity of zsh, if ever.

As a token, I go to my git.git repository in fish, I do 'git show v<tab>' and I expect to see the list of version tags, like I see on bash, and zsh, and I see only files.

If zsh were 100% compatible to ksh for programming I would consider it, but it isn't. Ksh/sh are standards, zsh/bash/tcsh are shells with a scripting language built in.

Somewhere in 1997ish I reported a bug in the AT&T public release of ksh to David Korn. I demonstrated a case in which ksh didn't conform to the behavior documented in his book, "The Korn Shell". He replied to me, "If the book says it and the shell doesn't do it, that's a bug," and it was fixed in the next release.

From the docs I infer that the emulation mode makes zsh mostly command option compatible with ksh, as well as setting some environmental setting to conform to the default settings of ksh. I asked how syntactically and behaviorally compliant with the ksh standard zsh is.

zsh works well for Arch. Autopopulates tab complete with service names for systemctl, automatically knows to choose the tgz file when using pacman -U. Does an decent job of error correction unless you are piping commands. I wish it would fix my flakyness on sudo though, like:
You do not have permissions....did you mean sudo ...

In a word: flexibility. Zsh is much more customizable and scriptable than Bash. (And scripting in Zsh is also much nicer than in Bash.) There's are very few things in Zsh that can't be customized either by changing a setting or by writing small scripts. Two small examples: Having ssh commands complete hostnames from ~/.ssh/config instead of ~/.ssh/known_hosts is a tiny two-liner. Another is having different completion styles for different things. My completion for directory contents is the standard style but my completion for the kill command is a full-menu style that actually shows my active processes.

Another great example is the builtin vcs_info system. It is second-to-none for putting information from various VCS systems in your prompt using a small and consistent syntax. And like most things in Zsh, it is insanely customizable:

I go the other direction and prefer AT&T Korn shell. Then I have the same behavior cross platform, and all of its wonderful process control goodness. Bash supports most of it, but it can be buggy and inconsistent across versions. I don't need a shell to be MORE bloated than bash.

I do, and it's screen. Better command-line syntax, and zmodem support lets me push files over the terminal connection; extremely useful on devices I've worked on with serial consoles and dead networking.

Zsh is absolutely wonderful in every single way. The syntax differs only very slightly from Bash. In fact for most cases it's useful to think of Zsh as being a superset of Bash. I say this first because oftentimes these sorts of threads fill up with people who worry that using Zsh on their own stuff will hamper them if ever they're in an environment where it isn't available to them, but that's really not been my experience at all. Ultimately there isn't really anything you can do using Zsh that's impossible to do with Bash. Going from one to the other is no great hardship if you're worried about consistency.

What really makes Zsh useful are all the bonus features and addons. Advanced globbing, syntax-highlighting, tab-completetions, global aliases. That sort of thing. Very nice things to have, really.

APPEND_HISTORY - if you have multiple Zsh sessions at the same time, they all append their history to your histfile. So, if you run a command in one window, that will appear in your history in all the other windows as well.

Append history while I'm su-ed - I tend to su to a service user quite often, and I want those commands to show up in my history as well. By some environment variable magic while I su, I have that user using all my Zsh files (config, history, etc.), so it's a much more seamless experience.

Host autocompletion from .ssh/known_hosts - Zsh will parse the list of hosts that you've SSH-ed to, and it will autocomplete those for networking-related commands (ssh, scp, ping, etc.). This is huge for me, because I SSH back and forth to hosts all the time. It's just become habit for me to do ssh gi<tab>1<tab> instead of git-01.sec.domain.local. Whenever someone sees me do it, they think it's some kind of magic.

Ability to have commands not go to your histfile - As much as I hate providing a password on the command line, there's an option that if you prepend your command with a space, it won't get saved to your history. This helps me make sure that any sensitive data I type doesn't get saved.

Coming from bash, this was all very cool to me. I haven't looked at other shells, but Zsh does what I need.

I am however seeing a fundamental difference in how histappend works in Bash versus APPEND_HISTORY in Zsh. It looks like Bash only writes to the history file on exit, and only reads the history file on start. It looks like there are some ways to fix this, at least somewhat.

I started using Unix in 1992 and Linux in 1995. By quick count I've administrated at least 12 different types of Unix (SVR4, SunOS, *BSD, AIX, Ultrix, IRIX, HP/UX, A/UX, Solaris, OSF/1, Linux off the top of my head) and almost as many distros of Linux. I've been through every flavor of the week during that period and I've been lured by flash and glitz time and time again. What truly interests me is reliability, stability and conformance to standards.

I see some of the stuff that zsh can do that's cool, but I admin several hundred compute nodes and log into at least a dozen machines every day. I need a real good reason to switch from what's default on multiple distros. I was wanting to be convinced, but I guess that's not happening today.

TL;DR: I'm not biased, I'm jaded.

Edit: I just went back and looked. I didn't realize it was your video, sorry if I insulted you.

I'm increasingly seeing Zsh being recommended, but I'm having trouble finding a useful eplanation about its advantages vs bash.

because most of the recommendations are blog posts written by clueless zsh fanboys who don't know %95 of the all zsh features and %99 of the zsh features they've mentioned in their blog posts are already available and configurable in bash.

not that i claim zsh doesn't have some features bash lacks, but they are very few and don't worth all the fuss on zsh.

I once came to like zsh on my own personal boxes, and those boxes of friends I'd occasionally offer support to. However at work there are hundreds of servers without zsh and it's not permitted to install other software (as silly as that is.) So I've gone back to using bash on my own servers due to habits. Similar to trying to use 'ls' on Windows.

Bash has caught up to Zsh in some ways. Bash has somewhat decent tab-completion now. While Zsh is awesome to use, it's weird to write shell scripts for (ex: zsh indexes Arrays starting at 1, not 0). Also, you will find bash installed by default on just about any server.

Most of what I would have said has already been said here, so I'll only add: zsh has sane startup file behavior. Bash tries too hard to do what Bourne did, which ends up making it nearly impossible to get anything read when you're using a non-interactive non-login shell.

I'm sticking with bash because it's the default and after ten years of using Linux desktops, I haven't reached a point where I feel limited with bash, on the contrary, I still learn new stuff quite frequently.

Not saying zsh isn't superior, it probably is, and if it remains that way it will eventually become the default, then I'll use it.

As /u/bunz pointed out this has nothing to do with the shell. As far as I know every instance of vim allows this by using the V command to select lines and then ctrl+f to page down (or down arrow to line down) while still selecting the text.