# Shells

What's your favorite shell for sysadmin work?

* Ash
* Bash
* Busybox
* Csh or Tcsh
* Dash
* Fish
* Korn
* Zsh

You may have heard the expression "when all you have a hammer, all problems look like nails".
That doesn't apply to the wonderful world of [POSIX](https://opensource.com/article/19/7/what-posix-richard-stallman-explains) shells.
To the uninitiated, one glowing black screenful of green text is the same as any other glowing black screenful of green text, many sysadmins know that the shell you choose can change every facet of how you interact with your computer.

It's not uncommon to find this out the hard way, usually under pressure.
Once you experience the impotence of entering the incorrect syntax into an unfamiliar shell, though, you quickly develop an attachment to the one you're comfortable in.
Even so, most popular shells have virtues that cause different sysadmins to set them as the default interface.
If you spend a little time with each one, you might find that you develop a new favourite, or at least that you can settle into a reliable backup shell.

Here are some of the most popular shells, and what users love about them.

## Ash and Dash

The Almquist shell was developed as a clone to the famous Bourne shell (not to be confused with the Bourne Again Shell, otherwise known as Bash).
It was kept intentionally lightweight, probably for the same reason line editing and [history](https://www.redhat.com/sysadmin/parsing-bash-history) were originally excluded: Kenneth Almquist felt that extra UI functions belonged outside the shell.
Decades later, the shell is a still a favorite small and basic shell. 
It was shipped with Android's initial releases, and it was a common default shell for the minimal boot environment of Linux distributions for many years.

As with many POSIX shells, using Ash is nominally familiar to anyone accustomed to a console.
You type commands, you get output. 
Some of the extra features are there, others are missing.
For instance, if you're used to using Emacs or Vim style keyboard shortcuts, you'll find them noticeably absent from Ash.
However, you can enable them (as long as they've been included at compile time) with the ``-E`` (for Emacs) or ``-V`` (for Vim) option.
History (actually the ``fc`` builtin command in Ash) isn't a given, either, depending on how Ash was compiled.
There are no arrays, and the trap builtin command accepts no options.

Dash is an Almquist shell, and is in fact a port of Ash from NetBSD to Debian Linux, and stands for *Debian Almquist Shell*.

Ash's best feature is also its greatest limitation.
It's a minimal shell, so if you're looking for simplicity then this is the shell for you.

## Bash 

The [Bourne-Again Shell](http://gnu.org/software/bash) (Bash) was created by the [GNU project](http://gnu.org) to replace the proprietary Bourne shell (which itself was created to replace Ken Thompson's shell).
Today, Bash is more than just a shell: it's a legitimate programming language, one of the main tools of the resourceful sysadmin, and nearly a cultural icon for non-programmers in need of quick and dirty automation.
If you can spend a day in a Linux shell, then you can develop a Bash script to replace yourself.
It's simple, direct, and surprisingly powerful, with features that include [arrays](https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays), [a directory stack](https://opensource.com/article/19/8/navigating-bash-shell-pushd-popd), [traps](https://opensource.com/article/20/6/bash-trap), substring parsing, [Emacs](https://opensource.com/resources/what-emacs) or [Vim](https://opensource.com/resources/what-vim) keyboard shortcuts, and much more.

One common argument *against* Bash is its size, which on my system is about 1 MB compared to 200 KB for Ash.
Another is its complexity.
Bash is so feature-rich that while a script written in pure POSIX will run in Bash, the same isn't always true for a Bash script attempting to run in a pure POSIX shell.
While Bash does have a POSIX mode, its extra "Bashisms" are usually too appealing to ignore.
The good news is that Bash is open source, so it can easily be installed to run a script full of Bash-isms, but some users object on principle nevertheless.

Bash is a flexible and powerful shell and has displaced other shells as the default on many systems.
Learn Bash, and you'll experience a modern and feature-rich shell that shows every sign of getting friendlier and friendlier as it continues to develop.

## Busybox

BusyBox is a multi-call binary that combines many common POSIX utilities into a single executable.
In other words, it's the core POSIX user interface all in one binary.
When installed from source code, it places a ``busybox`` executable in your system's library, and you're expected to link to it when creating individual commands for yourself and your users.
For example:

```
$ ln --symbolic /lib64/busybox/busybox gzip
$ gzip --help 
BusyBox v1.28.1 (2020-07-13 11:42:31 NZST) multi-call binary.

Usage: gzip [-cfkdt123456789] [FILE]...
```

In under 1 MB, you get around 400 commands, including **ls**, **cd**, **cp**, **mv**, **grep**, **ps**, **passwd**, **poweroff**, **printf**, **sed**, compression utilities, process management, and much more.
Most of these commands are minimal compared their GNU equivalents, but depending on your use case they're likely sufficient.
Likewise, Busybox's interactive shell is Ash, so it meets POSIX specifications and provides little else. 

## Csh or Tcsh

The C Shell (``csh``), and its later incarnation ``tcsh``, use a C-like (or C++ or Java, in case you're more familiar with those) syntax.
For instance, here's an ``if`` loop in Bash:

```
v=1

if [[ $v == 1 ]]
  then
  echo "verbose"
fi
```

And here's the same in Csh:

```
set v=1

if ($v == 1) then
  echo "verbose"
endif
```

The difference is subtle, but for people accustomed to the syntax of C and similar languages, there are enough small differences to noticeably improve their experience.
Some built-in commands are missing, too.
For instance, there's no ``type`` or ``hash`` commands in ``tcsh``, and you can't define your own functions.

While ``csh`` suffers somewhat from its age, ``tcsh`` is a good update and has most of the same capabilities as Bash, albeit with some different syntax from time to time.

## Fish

The Fish shell proudly calls itself "a modern shell for the 90s".
It's got all the benefits of robust shells like Bash and Zsh, but with added features such as syntax highlighting, a ``fish_config`` command, and [much more](https://opensource.com/article/20/3/fish-shell).
Its aim is to provide additional context to the user, and a better configuration management system than just a single ``.bashrc``.

There are slight differences in syntax here and there.
For instance, this is a function definition for Bash:

```
function sshrm() { 
  /usr/bin/sed -i "$1d" $HOME/.ssh/known_hosts
}
```

The same in Fish, however:

```
function sshrm
  /usr/bin/sed -i "$1d" $HOME/.ssh/known_hosts
end
```

Fans of Fish love its easy theming capabilities and the way it defaults to a directory of config files rather than a ``.bashrc`` file that at best sources other dot-files.

## Korn

The Korn shell (``ksh``) was developed by David Korn and released in 1983.
While both Bash and ``tcsh`` have shipped as the default shells for popular POSIX systems, the Korn shell has largely remained an "alternative" shell.
But as alternative shells go, ``ksh`` has done well for itself, and when Microsoft presented Powershell at tech conferences, they cited the Korn shell as its main influence.

There are a few different versions of Korn shell (mksh, ksh93, ksh93u+, ksh2020, and others), but the official branches are maintained on [AT&T's Github](https://github.com/att/ast).

To Bash uers, ``ksh`` is likely to feel pretty familiar.
Reading a [tutorial on Korn scripting](https://developer.ibm.com/technologies/systems/articles/au-kornshellscripting/) is nearly the same as reading on on Bash scripting.
You can define your own functions, create aliases, write loops, and even program tabbed completion options.
Emacs keybindings are enabled by default, but you can switch to ``vi`` keybindings using the ``-o vi`` option at launch, or by placing ``set -o vi`` in your ``~/.environ.ksh`` configuration file.

What Kornshell lacks, you probably won't notice immediately.
For instance, you can't enable or disable built-in commands, and there's a built-in command called ``whence`` that does the same job as the ``which`` executable.
There's no ``typeset`` command, but Kornshell does have arrays with most essential lookup features available.
In other words, while there are minor differences, ``ksh`` is easy to use for anyone accustomed to Bash or Fish or Zsh.

## Zsh

The [Z Shell](https://opensource.com/article/19/9/getting-started-zsh) (``zsh``) is an interactive Bourne-like POSIX shell known for its abundance of innovative features. 
Z Shell users often cite its many conveniences and credit it for increased efficiency and extensive customization.
When first launched, Zsh offers several configuration options, such as your history size, keybindings (Emacs or Vim), and just how many extra features you want.
For instance, you can make the ``cd`` command implicit by allowing Zsh to initiate a directory change when you provide a non-executable path with no command. 
There are several extra features, and you can set or unset them by editing the ``.zshrc`` configuration file.

There are a few subtle differences in syntax between Bash and Zsh, but few are commands that are often scripted, so the liklihood of you having to adapt scripts are low.
For instance, to disable a built-in command in Bash:

```
$ enable -n cd
```

In Zsh, the command is a little more intuitive:

```
$ disable cd
```

To rebuild cached command paths in Bash, you must clear the existing one, but in Zsh there's an option for it:

```
$ hash -f
```

There are small boons for those migrating from other shells, too.
For instance, you can use the ``whence`` command in Z Shell, which would be familiar for users of the Korn shell.

Zsh is a fun and dynamic mix of old and new features, and it's got a vibrant community developing themes and plugins for it.
These are [easy to install](https://opensource.com/article/19/9/adding-plugins-zsh) and add even further functionality to your shell, making Z Shell a contender for the most flexible shell available.

## Choose your shells

As usual with open source, you don't actually have to choose only one of any given tool.
While I'm a devoted Bash user at home, I often default to ``tcsh`` out of habit at work, because many of the scripts in the visual effects industry were written for C Shell.
To this day, I compulsively write [Git hooks](https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6) in ``tcsh`` for that reason.

You don't necessarily have to justify your choice of shell.
Use what works best for you and your team.
As long as it's open source, you've made a great choice.