Bash – Am I using bash after this ordeal

bashosxshellshell-scriptsu

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

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.

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:

set | grep ^BASH

with

env | grep ^BASH

Both set and env display environment variables. set is a shell built-in, and it sees the BASH_* variables. env is an external program, and you'll notice that it doesn't see the BASH_* 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:

$ export BASH_VERSION
$ env | grep ^BASH
BASH_VERSION=4.2.36(1)-release

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 of export -p to figure out which variables are going to be exported in this way.

Related Question