root@localhost:~# unset -v z ; cat srcpath ; bash srcpath ; ./srcpath ; "${z=$PWD/srcpath}" ; bash "$z" [[ ${z=$BASH_SOURCE} == /* ]] && t=$z || t=$PWD/$z printf %s\\n "$t" /root/srcpath /root/./srcpath /root/srcpath /root/srcpath
On Thu, Jan 26, 2023, 12:51 AM Sergei Trofimovich <sly...@gmail.com> wrote: > 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 > >