#1069978 bash: incorrect value of $BASH for login shells

Package:
bash
Source:
bash
Description:
GNU Bourne Again SHell
Submitter:
Gioele Barabucci
Date:
2025-10-19 01:01:02 UTC
Severity:
normal
Tags:
#1069978#5
Date:
2024-04-27 22:23:35 UTC
From:
To:
Hi,

bash 5.0 and 5.2 do not set $BASH to the right value when bash is used
as the login shell:

     $ apt install bash-static
     $ getent passwd $USER | cut -d: -f 7
     /bin/bash

     $ su $USER -s /bin/bash-static -c 'echo $BASH; readlink
/proc/$$/exe; true'
     /usr/bin/bash-static
     /usr/bin/bash-static

     $ su -l $USER -s /bin/bash-static -c 'echo $BASH; readlink
/proc/$$/exe; true'
     /bin/bash
     /usr/bin/bash-static

(bash-static is not a link to bash)

Bash also uses the value in /etc/passwd when in login mode, although the
documentation says

 > BASH   Expands to the full filename used to invoke this instance of bash.

"full filename" could be interpreted both as "an absolute filename" as
well as "the canonical absolute path".

     $ su $USER -s /bin/bash -c 'echo $BASH; readlink /proc/$$/exe; true'
     /usr/bin/bash
     /usr/bin/bash

     $ su -l $USER -s /bin/bash -c 'echo $BASH; readlink /proc/$$/exe; true'
     /bin/bash
     /usr/bin/bash

Regards,

#1069978#12
Date:
2024-04-28 19:07:18 UTC
From:
To:

     $ su $USER -s /bin/bash-static -c 'echo $BASH; readlink
/proc/$$/exe; head -1z /proc/$$/cmdline; echo'
     /usr/bin/bash-static
     /usr/bin/bash-static
     bash-static

     $ su -l $USER -s /bin/bash-static -c 'echo $BASH; readlink
/proc/$$/exe; head -1z /proc/$$/cmdline; echo'
     /bin/bash
     /usr/bin/bash-static
     -bash-static

Regards,

#1069978#17
Date:
2024-04-28 20:50:22 UTC
From:
To:
So argv[0] == "-bash-static", which causes $0 to be set to -bash-static
and internally sets shell_name to "bash-static" and login_shell to 1
(which notes that bash was executed with argv[0][0] == '-').

Then when you get to setting $BASH, this code gets executed:

   if ((login_shell == 1) && RELPATH(shell_name))
     {
       if (current_user.shell == 0)
         get_current_user_info ();
       name = savestring (current_user.shell);
     }

which has been the way bash has behaved since the bash-1.x days. Is
this enough of an issue to change behavior that dates back that far?

#1069978#22
Date:
2024-04-28 18:01:12 UTC
From:
To:
What does `su' pass to bash in argv[0]?
#1069978#27
Date:
2024-04-28 18:01:12 UTC
From:
To:
What does `su' pass to bash in argv[0]?
#1069978#32
Date:
2024-04-28 22:18:43 UTC
From:
To:
The bash manual defines $BASH as follows:
So, either the code or the manual should be changed.

I see why changing such an old behavior for the sake of correctness may
not be worth the risk of breaking somebody's workflow. But at the same
time it is hard to believe that anybody may be relying on "$BASH
contains the user shell set up in /etc/passwd when read from a login shell".

In my case, I intended to use $BASH to make sure that the right binary
was picked up by a certain test. I assume I'm not the only one using it
in that way.

Regards,

#1069978#37
Date:
2024-04-29 14:26:22 UTC
From:
To:
I think the original intent of this code -- it was a very long time ago --
was that a login shell either came from login/getty/xterm or su. If it came
from su, the name in argv[0] was either "-su" (the traditional behavior of
`su -'/`su -l') or the user's login shell. The Linux-specific business of
specifying the shell to use didn't come along until much later. Non-Linux
systems still put "su"/"-su" in argv[0].

In that light, it's easy to see what's happening. You want to change "-su"
to something reasonable, and the user's login shell is what su always uses.
If it's already the login shell, no loss.

I think we can fix this Linux issue by checking for and changing "-su"/"su"
to the login shell and letting other pathnames through.