diff options
Diffstat (limited to 'src/content/en/tils/2021/01/17/posix-shebang.adoc')
-rw-r--r-- | src/content/en/tils/2021/01/17/posix-shebang.adoc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/content/en/tils/2021/01/17/posix-shebang.adoc b/src/content/en/tils/2021/01/17/posix-shebang.adoc new file mode 100644 index 0000000..5cf0695 --- /dev/null +++ b/src/content/en/tils/2021/01/17/posix-shebang.adoc @@ -0,0 +1,58 @@ += POSIX sh and shebangs + +:awk-1: link:../../../2020/12/15/shellcheck-repo.html +:awk-2: link:../12/curl-awk-emails.html + +As I {awk-1}[keep moving] {awk-2}[towards POSIX], 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: + +[source,sh] +---- +#!/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: + +[source,sh] +---- +#!/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: + +[source,sh] +---- +#!/bin/sh +set -eu +---- + +. when running via `./script.sh`, if the system has an executable at `/bin/sh`, + it will be used to run the script; +. when running via `sh script.sh`, the sh options aren't ignored as previously. + +TIL. |