Jonathan Bowman
Posted on February 23, 2021
After exploring portable scripting in the previous article, I built a container available on Docker Hub, useful for testing and experimentation.
The container is an Alpine Linux container with the following tools:
- posh shell (this is the default)
- dash shell
-
rlwrap to offer readline support for either of the above shells (
rlwrap posh
is the default command if none specified) - checkbashisms for rooting out Bash-specific idiosyncrasies in scripts
- shellcheck for shell script linting
See the "Writing Bash Scripts that are not only Bash" for explanation and usage of the above.
Using the container
(Podman also works fine in any of the examples below.)
First, pull the image:
docker pull docker.io/bowmanjd/posix-playground
Note that the default user is shelly
and the home directory is /home/shelly
To launch posh: Policy-compliant Ordinary SHell with readline support:
docker run -it bowmanjd/posix-playground
To instead launch dash shell with readline support:
docker run -it bowmanjd/posix-playground rlwrap dash
(Without rlwrap
, line editing in either of these shells is impossible, making experimentation rather painful. Using rlwrap
is recommended.)
Note that the container runs as an unprivileged user (as common sense dictates!) named shelly
and the home directory is /home/shelly
.
To make every file in the host's current working directory available from within the home directory inside the container, you might bind mount the current directory like this:
docker run -it -v "$(pwd):/home/shelly" bowmanjd/posix-playground
If using rootless podman, you will find it convenient to add the :z
SELinux label to the bind mount to indicate a shared volume, allowing read-write acces, then use the keep-id
user namespace in order to map the user id of shelly
to your current user, as follows:
podman run -it --userns=keep-id -v "$(pwd):/home/shelly:z" bowmanjd/posix-playground
To check a helloworld.sh
shell script in the current directory for "bashisms" (make sure the first line, the "shebang", reads #!/bin/sh
):
cat helloworld.sh | docker run -i bowmanjd/posix-playground checkbashisms
To check a helloworld.sh
shell script in the current directory for a variety of gotchas:
cat helloworld.sh | docker run -i bowmanjd/posix-playground shellcheck -
Be sure to include the -
on the end: shellcheck -
to let shellcheck know to expect stdin, as you are "piping" the script file contents into shellcheck as standard input.
To simply run a script using posh:
docker run -i -v "$(pwd):/home/shelly" bowmanjd/posix-playground posh myscript.sh
Posh: an obscure shell with great usefulness
Of the tools included in the image, posh is the winner for me. It is not available on every distro, so having a container available is quite convenient.
Posh is also quite strict, and this is the point. It does not have any syntactic sugar to make it more Bash-like. I feel quite reassured when a script runs correctly in posh.
If you have other tools to recommend, or want to reflect on your experiences with this container image, feel free to contact me!
Posted on February 23, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.