diff options
Diffstat (limited to '_tils')
-rw-r--r-- | _tils/2021-01-17-posix-sh-and-shebangs.md | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/_tils/2021-01-17-posix-sh-and-shebangs.md b/_tils/2021-01-17-posix-sh-and-shebangs.md new file mode 100644 index 0000000..938d1bd --- /dev/null +++ b/_tils/2021-01-17-posix-sh-and-shebangs.md @@ -0,0 +1,57 @@ +--- + +title: POSIX sh and shebangs + +date: 2021-01-17 + +layout: post + +lang: en + +ref: posix-sh-and-shebangs + +--- + +As I [keep moving][posix-awk-0] [towards POSIX][posix-awk-1], I'm on the process of migrating all my Bash scripts to POSIX sh. + +As I dropped `[[`, arrays and other Bashisms, I was left staring at the first line of every script, wondering what to do: what is the POSIX sh equivalent of `#!/usr/bin/env bash`? +I already knew that POSIX says nothing about shebangs, and that the portable way to call a POSIX sh script is `sh script.sh`, but I didn't know what to do with that first line. + +What I had previously was: +```shell +#!/usr/bin/env bash +set -Eeuo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")" +``` + +Obviously, the `$BASH_SOURCE` would be gone, and I would have to adapt some of my scripts to not rely on the script location. +The `-E` and `-o pipefail` options were also gone, and would be replaced by nothing. + +I converted all of them to: +```shell +#!/bin/sh -eu +``` + +I moved the `-eu` options to the shebang line itself, striving for conciseness. +But as I changed callers from `./script.sh` to `sh script.sh`, things started to fail. +Some tests that should fail reported errors, but didn't return 1. + +My first reaction was to revert back to `./script.sh`, but the POSIX bug I caught is a strong strain, and when I went back to it, I figured that the callers were missing some flags. +Specifically, `sh -eu script.sh`. + +Then it clicked: when running with `sh script.sh`, the shebang line with the sh options is ignored, as it is a comment! + +Which means that the shebang most friendly with POSIX is: + +```shell +#!/bin/sh +set -eu +``` + +1. when running via `./script.sh`, if the system has an executable at `/bin/sh`, it will be used to run the script; +1. when running via `sh script.sh`, the sh options aren't ignored as previously. + +TIL. + +[posix-awk-0]: {% link _tils/2020-12-15-awk-snippet-shellcheck-all-scripts-in-a-repository.md %} +[posix-awk-1]: {% link _tils/2021-01-12-awk-snippet-send-email-to-multiple-recipients-with-curl.md %} |