On Mountain Lion, host Coguaro
, I login as user coconutpowder
using bash
:
Coguaro:~ coconutpowder$ echo $0
-bash
I need to run a command with elevated privileges so I try to su
switch to root
but it won't let me:
Coguaro:~ coconutpowder$ su -
Password:
su: Sorry
Feir enough. I read the man
page for su
and get this:
PAM is used to set the policy su(1) will use.
In particular, by default only users in the ``admin'' or ``wheel''
groups can switch to UID 0 (``root'').
I notice I am not part of either group allowed to su
by doing this:
Coguaro:~ coconutpowder$ id
uid=502(coconutpowder) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts)
so I re-run the su
command prefixing it with a sudo
, which I am allowed to do as I am in /etc/sudoers
:
/etc/sudoers: coconutpowder ALL=(ALL) ALL
Coguaro:~ coconutpowder$ sudo su -
Coguaro:~ root# echo $USER $0 $BASH_VERSION
root -sh 3.2.48(1)-release
Coguaro:~ root#
Now I have what I think is a problematic scenario as I am actually running sh
for what I can see, that is my login shell for root
after all, but I have the BASH_VERSION
environment variable set from my earlier login, passed along via the sudo
mechanism? Correct me if I am wrong.
This means some shell-detection tricks like this break:
if [ ${BASH_VERSION-not_running_within_bash} = not_running_within_bash ]; then
# ...
fi
I am at a total loss as to how to properly su
to root
and have some way of determining with certainty whether I am using bash
or not. The script uses Bash arrays extensively and could destroy filesystem paths if some values go spurious. I found the ps -p $$
hacks mentioned elsewhere a bit of a hack (?!) so I am looking for the best way to accomplish what I am trying to accomplish, considering I must login first as coconutpowder
and can't just do so as root
directly.
If I am doing the user switching wrong, I believe this question is distinctively different from the others that have proliferated around merely detecting the current (not "default" or "assigned") shell.
So far I am edging towards parsing $0, possibly removing any prefixed -
character to denote a login shell.
Unless any of you can teach me how to su
to root
with login (i.e. reading $HOME/.profile) and directly switch to bash
from the default sh
, which can't be changed.
Best Answer
Fortunately, you're wrong. The
BASH_VERSION
and similar environment variables are set, but not exported, so they don't exist for child processes.Compare the output of:
with
Both
set
andenv
display environment variables.set
is a shell built-in, and it sees theBASH_*
variables.env
is an external program, and you'll notice that it doesn't see theBASH_*
variables at all.If you did want to export those variables to child processes, you could do it manually, and then it would show up in
env
:But unless you've manually exported them like this, you can be fairly sure that the presence of
BASH_VERSION
means that you are actually running bash. See also the output ofexport -p
to figure out which variables are going to be exported in this way.