Sample Header Ad - 728x90

Is Bourne shell shebang #!/bin/sh expecting BASH POSIX-correct?

-3 votes
2 answers
226 views
I've recently been playing with the legacy Bourne Shell from the GitHub repo [heirloom-sh](https://github.com/grml/heirloom-sh) . It's installed at /usr/local/bin/sh with no symlinks. One script is invoking it via #!/bin/env sh. *I'm running Manjaro with system and packages fully up to date as of this post (vscodium-bin 1.99.02289-1, Manjaro 6.12.20-2-MANJARO). I posted concisely on their forum , but this issue goes way beyond even Arch stacks, affecting all Linux development.* ## Background Most of our Linux scripts are written for BASH (/bin/bash) and cannot work for Bourne Shell (implied by /bin/sh, but not reliable ). But, many coders still put #!/bin/sh for the shebang (#!/...) anyway, then code as if for the BASH #!/bin/bash. For most systems, /bin/sh is a link to /bin/bash, letting everything for BASH work in a mis-labaled Bourne Shell script. This has resulted in some sloppy programming practices and breaks the rule from Chemistry class: "Never make labels lie." For Debian, /bin/sh is a link to /bin/dash (Debian Almquist shell, POSIX minimal), carrying many Bourne Shell limits. So, Debian/Ubuntu devs might not run into the same problems of BASH scripts still working with #!/bin/sh. Thus, this may mostly be a non-Debian dev issue. ...mostly. # Examples of resulting errors ## Eg. VSCodium I first noticed this as a non-system issue with the AUR packages vscodium and vscodium-bin (I'm using vscodium-bin). /opt/vscodium-bin/bin/codium (where VSCodium resides) had this as line 1:
#!/usr/bin/env sh
...which would not start from the GUI, and then from the CLI threw this error:
/opt/vscodium-bin/bin/codium: syntax error at line 20: `YN=$' unexpected
I had two solutions: 1. Comment and changed the shebang line to this:
#!/usr/bin/bash
...then it worked. 2. Remove /usr/local/bin/sh (my legacy sandbox authentic Bourne shell, see above)... I reversed line 1 that so that /opt/vscodium-bin/bin/codium once again had this as line 1:
#!/usr/bin/env sh
...as it does OOB, then I removed /usr/local/bin/sh. Then it also worked. ***Technically, #!/usr/bin/env sh might not be POSIX compliant if it invokes BASH-only code.*** So, that would be an example of this coding issue happening with an actual project, VSCodium specifically. ## Eg. Manjaro Boot I mentioned this in my Manjaro Forum post , but basically having /bin/sh as an actual, true legacy /bin/sh Bourne shell broke my boot sequence. That tells me that many of my distro's most-current startup boot processes and scripts are actually using BASH code with a Bourne shell shebang. On Arch, not only Manjaro, /bin/sh is a symlink to bash, presuming the same PWD; it isn't even an absolute link, but a relative link! Arch:
# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 May  5  2025 /bin/sh -> bash
The boot issue on Manjaro is unlikely from developers changing an Arch file with #!/bin/bash into #!/bin/sh. Many of our implied, forgotten, invoked system startup scripts are probably inherited from the runlevel era. This is a legacy issue, after all. I'm scratching my head on how in the Linux-world that was even able to come from mainstream distro-level developers. # Summary We still have Bourne Shell artifacts in the form of #!/bin/sh floating around out there, even in our most current Linux distros, still being created in the developer world. If ever /bin/sh actually is /bin/sh, many Linux systems won't boot! This makes big problems for any portability. In fact, this might even be a security issue: Make /bin/sh actually become /bin/sh and every Linux server can't reboot. ___ These surrounding questions come to mind. How far does it reach into our Unix/Linux world to have /bin/sh --> bash? Is it POSIX compliant to use #!/usr/bin/env sh, then invoke code that only works with #!/bin/bash *and does not work* with #!/bin/sh? If POSIX compliant, why and would it break any other coding guidelines? Has the Linux world addressed BOLO to make sure we aren't using Bourne Shell (#!/bin/sh) in our scripts unless we are writing for the legacy Bourne Shell last updated for capabilities in 1989? Should we all be looking through our code and removing any #!/bin/sh meant to run on modern systems that probably have a link to /bin/bash anyway? Even consider removing the /bin/sh link to /bin/bash altogether? In light of not relying on sh at /bin/sh , if we thus should not use #!/bin/sh in referencing BASH code (that is if), then *theoretically* should Debian scripts use #!/bin/dash instead of #!/bin/sh? Or, is Debian's dash close enough to sh that it fits current POSIX expectations? How much has this already been discussed and what are the current resolutions across the Linux world? Is there another reason we need "labels to lie" and that using #!/bin/sh-labeled code (that can't run on actual 1989 Bourne Shell's /bin/sh) is a good idea? Does this issue only affect Linux or also Unix? Do Apple scripts use #!/bin/sh with symlink?
Asked by Jesse (355 rep)
Apr 5, 2025, 08:17 PM
Last activity: Apr 12, 2025, 04:30 PM