Test If Your Shell Scripts Are POSIX Compliant with ShellCheck
Even if you're using a Bash shebang you can run ShellCheck with the --shell flag to supply a different shell to check against.
I’ve done a video in the past about ShellCheck. It’s an excellent tool to perform static analysis against various flavors of shell scripts.
Often times I’ll try to create shell scripts that are POSIX compliant. This
usually means setting #!/usr/bin/env sh
as the Shebang and trying not to use
Bash specific features unless it makes sense. I’m very pragmatic about this
tho, if something is much more readable or easier to do with Bash I’ll use it
without fretting over it.
# Demo Video
Timestamped Table of Contents
- 0:08 – Two conditions, one is POSIX compliant and the other is not
- 0:38 – We can use the –shell sh flag with ShellCheck
- 1:10 – It’s useful to ensure compatibility when you want it
- 2:18 – The shorthand flag is -s sh
Code example
Follow along with touch demo && chmod +x demo
and then add this to the file:
#!/usr/bin/env bash
NAME="nick"
if [ "${NAME}" = "nick" ] || [ "${NAME}" = "nicholas" ]; then
echo "Shell compatible: Hey Nick!"
fi
if [[ "${NAME}" = "nick" || "${NAME}" = "nicholas" ]]; then
echo " Bash compatible: Hey Nick!"
fi
Verify that the script is functional:
$ ./demo
Shell compatible: Hey Nick!
Bash compatible: Hey Nick!
Confirm it’s compatible with bash
but not sh
:
# This will return no warnings since it's all good with Bash:
shellcheck demo
# Run ShellCheck with a custom shell to check against:
shellcheck --shell sh demo
The second command will throw this warning since it’s not POSIX compliant shell scripting:
In demo line 9:
if [[ "${NAME}" = "nick" || "${NAME}" = "nicholas" ]]; then
^-- SC2039: In POSIX sh, [[ ]] is undefined.
For more information:
https://www.shellcheck.net/wiki/SC2039 -- In POSIX sh, [[ ]] is undefined.
That’s because [[ ]]
was introduced specifically with Bash. There’s a bunch
of other things that are Bash specific too which is why having ShellCheck
around is great because you don’t need to keep all of the rules in your head.
For this specific example I’d prefer using the POSIX compliant shell version. In my opinion while the Bash version it is more concise it is less readable at a glance.
On the other hand double brackets offer convenient ways to do regular expression and string comparisons which I will use as needed. That’s something we can cover in a future post.
Reference Links
- https://github.com/koalaman/shellcheck
- https://shellcheck.net
- https://nickjanetakis.com/blog/when-to-use-long-word-or-short-letter-command-line-flags
How far down the POSIX compliance rabbit hole do you go? Let me know below.