Improper shebang in /usr/bin/yad-settings? [from yad-eos pkg]

I was looking into replacing usr/bin/sh with dash to improve shell performance on my up to date EndeavourOS (x86_64, 5.14.14-arch1-1) installation. However, I seem to have come across a bug of sorts in the usr/bin/yad-settings file. When I ran the checkbashisms script on all the #!/bin/sh shebang prefixed files in /usr/bin to identify any scripts utilizing non-posix compliant bash syntax, this file got basically spammed all over the command’s output log (log provided below).

Large portions of this file’s syntax is incompatible with usr/bin/sh (or usr/bin/dash). Since I didn’t remember ever actually using the yad-eos package, I tried removing it, but unfortunately it is a dependency for a lot of the other existing -eos packages. Is there any way to get around this? Why exactly is an official package improperly using shebang’s anyway(although I understand that this may be an issue upstream of this repo and out of EOS’s control). Has anyone else successfully migrated an EOS installation from sh to dash before who could tell me what I am missing; because afaik I can’t proceed without the #!/bin/sh prefixed files using proper syntax? Thanks.


(Relevant) Cmd-output: `checkbashisms`
$ find /usr/bin/ -type f -perm -o=r -print0 | xargs -0 gawk '/^#!.*( |[/])sh/{printf "%s\0", FILENAME} {nextfile}' | xargs -0 checkbashisms
possible bashism in /usr/bin/yad-settings line 28 ($RANDOM):
KEY=$RANDOM
possible bashism in /usr/bin/yad-settings line 61 ($"foo" should be eval_gettext "foo"):
yad --plug=$KEY --tabnum=1 --bool-fmt=t --quoted-output --separator=" " --form --scroll \
    --text=$"Main YAD settings and default values\n\n" \
    --field=$"Width of dialog window::NUM" \
    --field=$"Height of dialog window::NUM" \
    --field=$"Border width around dialog::NUM" \
    --field=$"Show remaining time and percentage in timeout progress bar:CHK" \
    --field=$"Combo-box in entry dialog is always editable:CHK" \
    --field=$"Default terminal command:" \
    --field=$"Default open command:" \
    --field=$"Default date format:" \
    --field=$"Default URI color in text-info dialog::CLR" \
    --field=$"Maximum number of tabs in notebook dialog::NUM" \
    --field=$"Use large previews in file selection dialogs:CHK" \
    --field=$"Search entry width::NUM" \
    --field=$"Ignore unknown command-line options:CHK" \
    --field=$"Enable debug mode with information about deprecated features:CHK" \
    -- \
    "$(gsettings get yad.settings width)!-1..32767" \
    "$(gsettings get yad.settings height)!-1..32767" \
    $(gsettings get yad.settings border) \
    $(gsettings get yad.settings show-remain) \
    $(gsettings get yad.settings combo-always-editable) \
    "$(eval echo $(gsettings get yad.settings terminal))" \
    "$(eval echo $(gsettings get yad.settings open-command))" \
    "$(eval echo $(gsettings get yad.settings date-format))" \
    "$(eval echo $(gsettings get yad.settings uri-color))" \
    $(gsettings get yad.settings max-tab) \
    $(gsettings get yad.settings large-preview) \
    $(gsettings get yad.settings search-width) \
    $(gsettings get yad.settings ignore-unknown-options) \
    $(gsettings get yad.settings debug) > $res1 &
possible bashism in /usr/bin/yad-settings line 65 ($"foo" should be eval_gettext "foo"):
themes=$"<Empty>!"
possible bashism in /usr/bin/yad-settings line 67 (should be VAR="${VAR}foo"):
    [[ $t == $SV_THEME ]] && themes+="^$t!" || themes+="$t!"
possible bashism in /usr/bin/yad-settings line 67 (alternative test command ([[ foo ]] should be [ foo ])):
    [[ $t == $SV_THEME ]] && themes+="^$t!" || themes+="$t!"
possible bashism in /usr/bin/yad-settings line 67 (should be 'b = a'):
    [[ $t == $SV_THEME ]] && themes+="^$t!" || themes+="$t!"
possible bashism in /usr/bin/yad-settings line 73 (should be VAR="${VAR}foo"):
    [[ $b == $HE ]] && homend+="^$b!" || homend+="$b!"
possible bashism in /usr/bin/yad-settings line 73 (alternative test command ([[ foo ]] should be [ foo ])):
    [[ $b == $HE ]] && homend+="^$b!" || homend+="$b!"
possible bashism in /usr/bin/yad-settings line 73 (should be 'b = a'):
    [[ $b == $HE ]] && homend+="^$b!" || homend+="$b!"
possible bashism in /usr/bin/yad-settings line 92 ($"foo" should be eval_gettext "foo"):
yad --plug=$KEY --tabnum=2 --bool-fmt=t --quoted-output --separator=" " --form --scroll \
    --text=$"YAD settings for text editor\nThis settings only usefull when YAD built with GtkSourceView\n\n" \
    --field=$"Default theme for text-info dialog::CB" ${themes%?} \
    --field=$"Show line numbers:CHK" $(gsettings get yad.sourceview line-num) \
    --field=$"Hightlight current line:CHK" $(gsettings get yad.sourceview line-hl) \
    --field=$"Enable line mars mode:CHK" $(gsettings get yad.sourceview line-marks) \
    --field=$"Color of first type marks::CLR" "$(eval echo $(gsettings get yad.sourceview mark1-color))" \
    --field=$"Color of second type marks::CLR" "$(eval echo $(gsettings get yad.sourceview mark2-color))" \
    --field=$"Right margin position::NUM" $(gsettings get yad.sourceview right-margin) \
    --field=$"Highlight matching brackets:CHK" $(gsettings get yad.sourceview brackets) \
    --field=$"Use autoindentation:CHK" $(gsettings get yad.sourceview indent) \
    --field=$"Smart Home/End behavior::CB" ${homend%?} \
    --field=$"Use smart backspace:CHK" $(gsettings get yad.sourceview smart-bs) \
    --field=$"Tabulation width::NUM" $(gsettings get yad.sourceview tab-width) \
    --field=$"Indentation width::NUM" $(gsettings get yad.sourceview indent-width) \
    --field=$"Insert spaces instead of tabulation:CHK" $(gsettings get yad.sourceview spaces) > $res2 &
possible bashism in /usr/bin/yad-settings line 98 ($"foo" should be eval_gettext "foo"):
yad --title=$"YAD settings" --key=$KEY --width=475 --height=600 --image=preferences-other \
    --button=$"Load defaults!view-refresh:3" --button="yad-save:0" --button="yad-close:1" \
    --text=$"<span size='xx-large' weight='bold'>YAD settings editor</span>" --text-align=center \
    --notebook --stack --expand --tab=$"Main" --tab=$"Editor"
possible bashism in /usr/bin/yad-settings line 100 (alternative test command ([[ foo ]] should be [ foo ])):
if [[ $? -eq 0 ]]; then
possible bashism in /usr/bin/yad-settings line 101 ('$(< foo)' should be '$(cat foo)'):
    eval r1=($(< $res1))
possible bashism in /usr/bin/yad-settings line 102 ('$(< foo)' should be '$(cat foo)'):
    eval r2=($(< $res2))
possible bashism in /usr/bin/yad-settings line 105 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings width ${r1[0]}
possible bashism in /usr/bin/yad-settings line 106 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings height ${r1[1]}
possible bashism in /usr/bin/yad-settings line 107 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings border ${r1[2]}
possible bashism in /usr/bin/yad-settings line 108 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings show-remain ${r1[3]}
possible bashism in /usr/bin/yad-settings line 109 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings combo-always-editable ${r1[4]}
possible bashism in /usr/bin/yad-settings line 110 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings terminal "${r1[5]}"
possible bashism in /usr/bin/yad-settings line 111 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings open-command "${r1[6]}"
possible bashism in /usr/bin/yad-settings line 112 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings date-format "${r1[7]}"
possible bashism in /usr/bin/yad-settings line 113 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings uri-color ${r1[8]}
possible bashism in /usr/bin/yad-settings line 114 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings max-tab ${r1[9]}
possible bashism in /usr/bin/yad-settings line 115 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings large-preview ${r1[10]}
possible bashism in /usr/bin/yad-settings line 116 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings search-width ${r1[11]}
possible bashism in /usr/bin/yad-settings line 117 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings ignore-unknown-options ${r1[12]}
possible bashism in /usr/bin/yad-settings line 118 (bash arrays, ${name[0|*|@]}):
    gsettings set yad.settings debug ${r1[13]}
possible bashism in /usr/bin/yad-settings line 121 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview theme "${r2[0]}"
possible bashism in /usr/bin/yad-settings line 122 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview line-num ${r2[1]}
possible bashism in /usr/bin/yad-settings line 123 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview line-hl ${r2[2]}
possible bashism in /usr/bin/yad-settings line 124 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview line-marks ${r2[3]}
possible bashism in /usr/bin/yad-settings line 125 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview mark1-color ${r2[4]}
possible bashism in /usr/bin/yad-settings line 126 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview mark2-color ${r2[5]}
possible bashism in /usr/bin/yad-settings line 127 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview right-margin ${r2[6]}
possible bashism in /usr/bin/yad-settings line 128 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview brackets ${r2[7]}
possible bashism in /usr/bin/yad-settings line 129 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview indent ${r2[8]}
possible bashism in /usr/bin/yad-settings line 130 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview homend ${r2[9]}
possible bashism in /usr/bin/yad-settings line 131 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview smart-bs ${r2[10]}
possible bashism in /usr/bin/yad-settings line 132 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview tab-width ${r2[11]}
possible bashism in /usr/bin/yad-settings line 133 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview indent-width ${r2[12]}
possible bashism in /usr/bin/yad-settings line 134 (bash arrays, ${name[0|*|@]}):
    gsettings get yad.sourceview spaces ${r2[13]}
possible bashism in /usr/bin/yad-settings line 135 (alternative test command ([[ foo ]] should be [ foo ])):
elif [[ $? -eq 3 ]]; then

File-contents: `/usr/bin/yad-settings`
#! /bin/sh
# -*- mode: sh -*-
#
# YAD settings editor. This file is part of YAD
#
# YAD is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# YAD is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# YAD. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2021, Victor Ananjevsky <ananasik@gmail.com>
#

TEXTDOMAIN=yad
TEXTDOMAINDIR=/usr/share/locale

res1=$(mktemp --tmpdir ys-tab1.XXXXXXXX)
res2=$(mktemp --tmpdir ys-tab2.XXXXXXXX)
trap "rm -f $res1 $res2" EXIT

KEY=$RANDOM

# first tab (values at the end due to possible hyphens)
yad --plug=$KEY --tabnum=1 --bool-fmt=t --quoted-output --separator=" " --form --scroll \
    --text=$"Main YAD settings and default values\n\n" \
    --field=$"Width of dialog window::NUM" \
    --field=$"Height of dialog window::NUM" \
    --field=$"Border width around dialog::NUM" \
    --field=$"Show remaining time and percentage in timeout progress bar:CHK" \
    --field=$"Combo-box in entry dialog is always editable:CHK" \
    --field=$"Default terminal command:" \
    --field=$"Default open command:" \
    --field=$"Default date format:" \
    --field=$"Default URI color in text-info dialog::CLR" \
    --field=$"Maximum number of tabs in notebook dialog::NUM" \
    --field=$"Use large previews in file selection dialogs:CHK" \
    --field=$"Search entry width::NUM" \
    --field=$"Ignore unknown command-line options:CHK" \
    --field=$"Enable debug mode with information about deprecated features:CHK" \
    -- \
    "$(gsettings get yad.settings width)!-1..32767" \
    "$(gsettings get yad.settings height)!-1..32767" \
    $(gsettings get yad.settings border) \
    $(gsettings get yad.settings show-remain) \
    $(gsettings get yad.settings combo-always-editable) \
    "$(eval echo $(gsettings get yad.settings terminal))" \
    "$(eval echo $(gsettings get yad.settings open-command))" \
    "$(eval echo $(gsettings get yad.settings date-format))" \
    "$(eval echo $(gsettings get yad.settings uri-color))" \
    $(gsettings get yad.settings max-tab) \
    $(gsettings get yad.settings large-preview) \
    $(gsettings get yad.settings search-width) \
    $(gsettings get yad.settings ignore-unknown-options) \
    $(gsettings get yad.settings debug) > $res1 &

# get list for themes
eval SV_THEME=$(gsettings get yad.sourceview theme)
themes=$"<Empty>!"
for t in $(yad-tools --show-themes); do
    [[ $t == $SV_THEME ]] && themes+="^$t!" || themes+="$t!"
done

# get list for home/end
eval HE==$(gsettings get yad.sourceview homend)
for b in never before after always; do
    [[ $b == $HE ]] && homend+="^$b!" || homend+="$b!"
done

# second tab
yad --plug=$KEY --tabnum=2 --bool-fmt=t --quoted-output --separator=" " --form --scroll \
    --text=$"YAD settings for text editor\nThis settings only usefull when YAD built with GtkSourceView\n\n" \
    --field=$"Default theme for text-info dialog::CB" ${themes%?} \
    --field=$"Show line numbers:CHK" $(gsettings get yad.sourceview line-num) \
    --field=$"Hightlight current line:CHK" $(gsettings get yad.sourceview line-hl) \
    --field=$"Enable line mars mode:CHK" $(gsettings get yad.sourceview line-marks) \
    --field=$"Color of first type marks::CLR" "$(eval echo $(gsettings get yad.sourceview mark1-color))" \
    --field=$"Color of second type marks::CLR" "$(eval echo $(gsettings get yad.sourceview mark2-color))" \
    --field=$"Right margin position::NUM" $(gsettings get yad.sourceview right-margin) \
    --field=$"Highlight matching brackets:CHK" $(gsettings get yad.sourceview brackets) \
    --field=$"Use autoindentation:CHK" $(gsettings get yad.sourceview indent) \
    --field=$"Smart Home/End behavior::CB" ${homend%?} \
    --field=$"Use smart backspace:CHK" $(gsettings get yad.sourceview smart-bs) \
    --field=$"Tabulation width::NUM" $(gsettings get yad.sourceview tab-width) \
    --field=$"Indentation width::NUM" $(gsettings get yad.sourceview indent-width) \
    --field=$"Insert spaces instead of tabulation:CHK" $(gsettings get yad.sourceview spaces) > $res2 &

# main dialog
yad --title=$"YAD settings" --key=$KEY --width=475 --height=600 --image=preferences-other \
    --button=$"Load defaults!view-refresh:3" --button="yad-save:0" --button="yad-close:1" \
    --text=$"<span size='xx-large' weight='bold'>YAD settings editor</span>" --text-align=center \
    --notebook --stack --expand --tab=$"Main" --tab=$"Editor"

if [[ $? -eq 0 ]]; then
    eval r1=($(< $res1))
    eval r2=($(< $res2))

    # Main settings
    gsettings set yad.settings width ${r1[0]}
    gsettings set yad.settings height ${r1[1]}
    gsettings set yad.settings border ${r1[2]}
    gsettings set yad.settings show-remain ${r1[3]}
    gsettings set yad.settings combo-always-editable ${r1[4]}
    gsettings set yad.settings terminal "${r1[5]}"
    gsettings set yad.settings open-command "${r1[6]}"
    gsettings set yad.settings date-format "${r1[7]}"
    gsettings set yad.settings uri-color ${r1[8]}
    gsettings set yad.settings max-tab ${r1[9]}
    gsettings set yad.settings large-preview ${r1[10]}
    gsettings set yad.settings search-width ${r1[11]}
    gsettings set yad.settings ignore-unknown-options ${r1[12]}
    gsettings set yad.settings debug ${r1[13]}

    # GtkSourceView settings
    gsettings get yad.sourceview theme "${r2[0]}"
    gsettings get yad.sourceview line-num ${r2[1]}
    gsettings get yad.sourceview line-hl ${r2[2]}
    gsettings get yad.sourceview line-marks ${r2[3]}
    gsettings get yad.sourceview mark1-color ${r2[4]}
    gsettings get yad.sourceview mark2-color ${r2[5]}
    gsettings get yad.sourceview right-margin ${r2[6]}
    gsettings get yad.sourceview brackets ${r2[7]}
    gsettings get yad.sourceview indent ${r2[8]}
    gsettings get yad.sourceview homend ${r2[9]}
    gsettings get yad.sourceview smart-bs ${r2[10]}
    gsettings get yad.sourceview tab-width ${r2[11]}
    gsettings get yad.sourceview indent-width ${r2[12]}
    gsettings get yad.sourceview spaces ${r2[13]}
elif [[ $? -eq 3 ]]; then
    # Load default settings
    gsettings reset-recursively yad.settings
    gsettings reset-recursively yad.sourceview
fi
3 Likes

There are a surprising number of Arch packages that specify /bin/sh and then contain bash syntax. This is probably a side effect of /bin/sh being bash by default on Arch.

@Kresimir complains about this regularly. :wink:

7 Likes

Indeed. You can’t replace /bin/sh with Dash on Arch, at least not without a lot of effort.

That’s pretty much the only thing that comes to my mind about Arch that is just inexcusably bad.

More info here:

4 Likes

Might be worth filing a bug against https://github.com/v1cont/yad .


Off-topic section

I’m slightly less critical of the use of dash as the default interpreter - scripts using sh should be POSIX compatible, no excuses. https://wiki.archlinux.org/title/Dash#Use_Dash_as_/bin/sh

Although… I also seem to remember someone saying that when bash is run from an sh symlink it does some special handling that means it loads a subset of functionality so it starts etc. more quickly… :thinking:

2 Likes

Welcome to the forum! :smile:

Does it work for you if you change it to #!/bin/bash?
I’m not using dash, just wanted to know…

If it works on default Arch install with #!/bin/sh, it should absolutely work if you change it to #!/bin/bash (on any system), because on default Arch installs, sh is symlinked to bash.

The only time it stops working is when you change sh to be something other than Bash, like Dash (like on Debian). This is why #!/bin/sh should only be used for strictly POSIX-compliant scripts and nothing else, and all scripts that use #!/bin/sh should be checked with checkbashisms utility to ensure this. Unfortunately, Arch repos are full of sloppy scripts that fail this simple criterion.

There are good reasons why someone might prefer to use Dash as sh, but on Arch, there is no practical way to do so, unfortunately. As stated elsewhere, I this is, in my view, a huge problem with Arch.

Seems that Arch has very many scripts having /bin/sh but using bash features…

About 7-8% scripts that are marked as POSIX-compliant (i.e. have #!/bin/sh) are not actually POSIX-compliant, based on my non-exhaustive search (limited sample: packages installed on my system). Could be more or less, when we consider the entirety of the Arch repos.

It’s not that many, but it’s enough to make it very impractical to use anything else other than Bash as sh.

I don’t think that is enforced in any meaningful way. You can do a simple test, make a script like this:

#!/bin/sh
# This is just a test, never do this in production code!
if (( 1+1 == 2 )); then
  echo -ne "Utterly bashist!\n"
fi

and this will work on a default Arch install, although it shouldn’t (and won’t if you use Dash for sh).

Now, it remains to test whether a strictly POSIX-compliant script that contains #!/bin/sh run on Bash performs any faster than the same script with #!/bin/bash (and whether introducing a simple bashism would eliminate this performance gain) and how it compares to same script with #!/bin/dash.

I’ll try to come up with some examples.

2 Likes

For the OP - is there a reason that crawling your installation, and replacing all !#/bin/sh with !#/bin/bash - THEN swap in dash, and using sh for your own stuff from there would be a problem? Or more accurately, check for bashisms, and change only those files?

Of course, you would have to rerun it after some kinds of updates I suppose…

Yes, that’s a huge problem.

  1. Modifying all POSIX scripts on the system is pointless, because then you do not take advantage of the amazing performance of Dash for strictly POSIX-compliant scripts. And if you are going to use Dash only for your own scripts, it’s far easier to just write #!/bin/dash in your scripts, instead of having to change every POSIX script on your system, on every update.

  2. Automating checking for Bashisms is a solution to this problem, but a really bad one. I made a program that ran checkbashisms on every installed POSIX script on my system (just to discover how many scripts are misleadingly labelled as POSIX). The program took the output of pacman -Qlq and ran every line of it through the file utility, generating a list of POSIX scripts, and then ran checkbashisms on every one of them. It took over an hour to get the results. Doing this on every update, on a rolling distro, is just not convenient.

After giving this issue more time than a reasonable person would, I concluded that there is no practical way to use Dash as /bin/sh on Arch Linux, which is inexcusable, but it is how it is.

2 Likes

Sometimes i wonder if Arch devs are relaxed about it because of AUR existence, since it will break anyway because they can’t control it’s content…

Still it’s such a soydev thing to do in official repos.

Bashisms in strictly POSIX scripts are just a subset of all possible errors. You could write gibberish in your scripts and put it on the AUR, and the result would be that your scripts do not work. They will return errors or do something unexpected, which is the expected behaviour of any program that contains errors.

Same thing with Bashisms in a POSIX compliant script, they should not work. The fact that they do work is simply due to the fact that Bash syntax is a superset of POSIX, and on Arch, all POSIX scripts are interpreted by Bash. A responsible implementation of Bash would switch to the POSIX-strict mode upon reading #!/bin/sh in the first line of the script, but Bash does not do that, see my example above. Bash developers do not care about that, they just want you to use Bash as the default shell. In fact, on any default Arch Linux install, one of the offending scripts that is incorrectly marked as POSIX compliant is bashbug a bug reporting script and it is part of the bash package! :exploding_head:

See for yourself:

checkbashisms /usr/bin/bashbug

There are many AUR packages that are broken. When that happens, users complain to the maintainer and the maintainer fixes the problem (or orphans the package).

1 Like

Hmmm - just blue-skying here… how about changing all found scripts to !#/bin/dash that are POSIX compliant, and trusting that updates will be marked as .pacnew? If I have that thought correctly, then the workload is reduced…

Not that I would do that, of course!

You can’t count on that, and you shouldn’t have to, because that’s not what the whole idea of .pacnew files is meant for.

In fact, that’s much less reliable than just trusting that the upstream will correctly provide an interpreter directive of #!/bin/sh for their POSIX compliant scripts.

That 100% won’t work. You don’t get .pacnew files when things are changed during an update. You only get .pacnew files when something in the backup array changes. Most packages don’t even have a backup array and the ones that do are generally files which the user is expected to change. i.e. configuration files.

Manually changing the files that a package writes in an Arch-based distro is a bad idea.

I did say that was a blue-sky scenario :grin: I didn’t expect it to actually work that way…

Personally, I have enough trouble with USING bashisms without worrying about whether they ought to be there!

I guess other distro types would better suit the OP - maybe Gentoo? I have to admit it seems strange to me that this situation exists, though - especially on Arch (and derivatives).

It is because bash is the default sh on Arch. This means that virtually everyone who tests sh scripts on Arch is using bash to do it. Because of that, nobody notices issues like this.

Realistically, issues should probably be opened up against all these packages to fix the shebang reference.

That is what I meant - I understood how it had happened, but I was not expecting to learn that the fix had not happened. I guess they don’t have enough devs free to tackle such an ‘esoteric problem’, especially as it works as is (provided you don’t switch out bash as your default!).

If I knew enough, I would probably volunteer - but I don’t! Oh well - I guess it is good that less than perfection can be found - if you look hard enough! Thanks for the clarifications…

The packages are all maintained by different people. If nobody takes the time to report the issue on each package, it isn’t likely to get fixed.

To be fair, identifying all the packages and opening and responding to issues on each would be fairly time consuming.