What's your favorite shell for sysadmin work?
You may have heard the expression, "when all you have is a hammer, all problems look like nails." That doesn't apply to the wonderful world of POSIX shells. To the uninitiated, one glowing black screenful of green text is the same as any other glowing black screenful of green text, but 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 favorite, 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 of 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 were originally excluded: Kenneth Almquist felt that extra UX functions belonged outside the shell. Decades later, the shell is 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, while 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 (Bash) was created by the GNU project 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, a directory stack, traps, substring parsing, Emacs or 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.
[ Download now: A sysadmin's guide to Bash scripting. ]
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. 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.
To Bash users, ksh
is likely to feel pretty familiar. Reading a tutorial on Korn scripting 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 (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 likelihood 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 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 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.
[ Free online course: Red Hat Enterprise Linux technical overview. ]
Seth Kenlon
Seth Kenlon is a UNIX geek and free software enthusiast. More about me