How to check your shell scripts for portability
This blog is mainly a reminder for myself for the various possibilities to check my shell scripts for portability, but maybe it’s helpful for some other people, too.
First, why bother? Well, while bash is the default /bin/sh
shell on
many rpm-based Linux distributions (so it’s also the default shell on the
systems I’m developing with and thus referring to here), it’s often not the
case on other Linux distributions like Debian or Alpine, and it’s certainly
not the case on non-Linux systems like the various *BSD flavors or illumos
based installations.
Test your scripts with other shells
The most obvious suggestion is, of course, to run your script with a different shell than bash to see whether it works as expected.
Using dash
The probably most important thing to check is whether your script works with
dash. dash is the default /bin/sh
shell on most Debian-based distributions,
so if you want to make sure that your script also works on such systems, this
is the bare minimum that you should check. The basic idea of dash is to run
scripts as far as possible, without adding bloat to the shell. Therefore the
shell is restricted to a minimum with regards to the syntax that it understands,
and with regards to the user interface, e.g. the interactive shell prompt is
way less comfortable compared with shells like bash.
Since dash is also available in Fedora and in RHEL via EPEL, its installation is as easy as typing something like:
Thus checking your scripts with dash is almost no additional effort and thus a very good place to start.
Using posh
posh stands for “Policy-compliant Ordinary SHell” – it’s another shell that has been developed within the Debian project to check shell scripts for POSIX compliance. Unlike dash, the syntax that this shell understands is really restricted to the bare minimum set that the POSIX standard suggests for shells, so if your script works with posh, you can be pretty sure that it is portable to most POSIX-compliant shells indeed.
Unfortunately, I haven’t seen a pre-compiled binary of posh for Fedora or RHEL yet, and I haven’t spotted a dedicated website for this shell either, so the installation is a little bit more complicated compared to dash. The best thing you can do on a non-Debian based system is to download the tar.xz source package from https://packages.debian.org/sid/posh and compile it on your own:
Using virtual machines
Of course you can also check your scripts on other systems using virtual machines, e.g. on guest installations with FreeBSD, NetBSD, OpenBSD or one of the illumos distributions. But since this is quite some additional effort (e.g. you have to boot a guest and make your script available to it), I normally skip this step – testing with dash and posh catches most of the issues already anyway.
Test your scripts with shell checkers
There are indeed programs that help you to check the syntax of your shell scripts. The two I’ve been using so far are checkbashism and ShellCheck:
Using checkbashism
checkbashism is a Perl script, maintained again by the Debian people to
check for portability issues that occur when a shell script has been only
written with bash in mind. It is part of the
devscripts package in Debian.
Fortunately, the script is also available in Fedora by installing the so-called
devscripts-checkbashisms
package (which can also be used on RHEL by way).
checkbashism focuses on the syntax constructs that are typically only available
in bash, so this is a good and easy way to check your scripts on distributions
where /bin/sh
is bash by default.
Using ShellCheck
ShellCheck is another static shell script analyzer tool which is available for most distributions or can ben installed via the instructions provided on its GitHub page. The nice thing about ShellCheck is that they even provide the possibility to check your script via upload on their www.shellcheck.net website – so for small, public scripts, you don’t have to install anything at all to try it out, just copy and paste your script into the text box on the website.