Hello bash maintainers! nixpkgs package collection likes to wrap binaies and shell scripts to pass extra environment variables via wrappers.
One example is dejagnu's runtest: $ cat `which runtest` | unnix #! /<<NIX>>/bash-5.2-p15/bin/bash -e PATH=... export PATH exec -a "$0" "/<<NIX>>/dejagnu-1.6.3/bin/.runtest-wrapped" "$@" Script's idea is to call .runtest-wrapped as if it had a 'runtest' name. It's especially important for `runtest` because it internally checks for own $0: mypath=${0-.} ... if [ "$target" != runtest ] ; then target="--target ${target}" else target="" fi To the bug: looks like 'exec -a' does not work for bash scripts, but does work for other executables. An example: Wrap C executable: $ cat b.bash #!/usr/bin/env bash exec -a "$0" $PWD/a "$@" $ cat a.c #include <stdio.h> int main(int argc, char * argv[]) { for (int i = 0; i < argc; ++i) { printf ("A[%i]='%s'\n", i, argv[i]); } } $ gcc a.c -o a Result: $ bash -x ./b.bash 1 2 3 + exec -a ./b.bash /home/slyfox/bugs/a 1 2 3 A[0]='./b.bash' A[1]='1' A[2]='2' A[3]='3' Works as expected: './a' sees './b.bash' as an argv[0]. Wrap 'bash' script: $ cat a.bash #!/usr/bin/env bash exec -a "$0" $PWD/foo "$@" $ cat foo #!/usr/bin/env bash echo "$0" "$@" Result: $ bash -x ./a.bash 1 2 3 + exec -a ./a.bash /home/slyfox/bugs/foo 1 2 3 /home/slyfox/bugs/foo 1 2 3 For some reason '-a ./a.bash' did not take an effect. Such a discrepancy makes these wrappers to break occasionally like in https://sourceware.org/PR30052. I fear it's a side-effect of the way 'bash' gets executed via shebang by kernel. But maybe not? Somehow direct script execution still manages to preserve script's name. Is it an intended behaviour that could not be easily changed? Or it's a bug? Thank you! -- Sergei