From GNU Bash to Fish

Throughout all of April I experimented with different shells. After using GNU Bash for nearly twenty years I wanted to sample some of the alternatives. I stayed true to my decision but I never revisited the subject to explain my experiences, opinions, and the reasons why I switched to Fish.

The release of Fish 2.0.0 three days ago reminded me to finally return here and write how it all went.

My growing dislike for Bash programming was the impetus that drove me to examine other shells. There are wonderful introductions and guides out there for Bash making it impossible to criticize the shell for a lack of documentation and support. But I became increasingly unhappy with Bash’s antiquated design and language. I often write shell scripts for small tasks and so those feelings sent me looking for a shell with a more simple and consistent programming language.

I began with rc, the default shell on Plan 9. Tom Duff’s explanation of rc’s design principles gave me hope:

Rc draws heavily from Steve Bourne’s /bin/sh. Any successor of the Bourne shell is bound to suffer in comparison. I have tried to fix its best-acknowledged shortcomings and to simplify things wherever possible, usually by omitting inessential features. Only when irresistibly tempted have I introduced novel ideas. Obviously I have tinkered extensively with Bourne’s syntax.

The simplification that Duff mentions felt like the best aspect of rc. Its language demands no oddly place semicolons, easily nests command substitutions, handles lists of strings, cannot screw up scripts by incorrectly treating a string with spaces as multiple words, and so on. Rc appeared an attractive choice. But I was not going to stop after trying only one alternative shell.

Xs was next on my list. The shell, based on es, provided a more functional approach to shell script programming. Other shells used strings for their primitive types, but xs used lists. This made for some convenient syntax, particularly since the amount of whitespace between list elements could be as long as desired. That made it possible to write less noisy code since xs commands accept lists. The xs manual provides a good example:

switch $x \
   error   { result 1 } \
   warning { break } \
   good    { echo no problem  }

switch $x (
   error   { result 1 }
   warning { break }
   good    { echo no problem  }

The whitespace allowed in lists eliminated most needs for escaping newlines characters. Xs rejected traditional comparisons via test and its many flags. Instead my scripts needed only ~, the pattern matching operator. The related ~~ operator was also interesting, performing the same comparisons as ~ but then extracting all matching elements of that comparison. I could use this to rather easily take sub-strings. And being a functional language, xs let me pass around blocks of code and lambdas as variables, arguments to other functions, et cetera. Although I must admit that I never found any particular use for the latter functionality.

As I experimented with these shells, however, I began to develop a different perspective of the situation.

How About No Shell Programming?

When I examined my shell scripts for Bash I realized there was nothing shell-ish about them, which is to say, I could have written them as easily in Python or Perl or Ruby if I had wanted. Why did I continue to write any code in shells with these great programming languages at my grasp? That thought made me decide that perhaps the improvement over Bash that I was seeking wasn’t related to scripting. So what other important merit was there to consider?

The interface.

If I was going to stop writing shell scripts altogether then I could still at least find a shell with a friendlier interface than Bash. This is when many people turn to Zsh. It has a great set of features, themes, plugins and more. Criticizing Zsh is a difficult task, which speaks to its quality. Truth be told, my choice of Fish over Zsh was more-or-less arbitrary. After using each exclusively for a few days I felt that they both provided the enhancements over Bash that I wanted, both in terms of their visual interfaces and their behavior for features such as the command history. In the end Fish felt ‘easier’ to use because it more closely aligned with some innate preference of mine, not because Fish is technical superior to Zsh—honestly I expect the opposite is true.

I am at a loss for how to best explain in text how one interactive shell is better to use than another. The Fish tutorial may provide some insight into why I’ve decided to stick with it. I will say this though: if you’re a programmer that uses shells on a regular basis then you owe it to yourself to examine the other alternatives out there, especially if you have used the same shell for a long time. Maybe you want something that is easier to script, something that is easier to customize, and maybe you’ll come to the conclusion that you prefer what you’re already using.

I tried to make the point earlier that I’ve given up on shell scripting, but the reality is that is not one-hundred percent true. There are some tiny custom Bash functions that I ended up porting over to Fish once I decided to continuing using it. So in a future article I will explain that relatively simple process, along with how to accomplish some common Bash tricks in Fish.


4 thoughts on “From GNU Bash to Fish

  1. […] Previously I wrote about my switch from GNU Bash to Fish. As a result I have given up writing shell scripts in favor of using Perl, Python, and similar languages. But there are a series of short functions from Bash that I decided to port over to Fish, as I did not feel they were large enough to warrant a script in one of those other languages. So today I want to share some custom Fish functions that I find useful. […]

Add Your Thoughts

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s