I'm trying to check whether the current shell session is running within a su
login session.
What's the best way to test this condition?
I'm trying to check whether the current shell session is running within a su
login session.
What's the best way to test this condition?
look into the logname
command. logname will print the username of the user who logged into the controlling terminal as provided by the utmp log.
tk-mbp:~ tkennedy$ id -g -rn
staff
tk-mbp:~ tkennedy$ id -u -rn
tkennedy
tk-mbp:~ tkennedy$ logname
tkennedy
tk-mbp:~ tkennedy$ su -
Password:
tk-mbp:~ root# id -g -rn
wheel
tk-mbp:~ root# id -u -rn
root
tk-mbp:~ root# logname
tkennedy
This example if from Mac OS X, so the use of the id
command may differ to other OSes, however, the use of logname is consistent between Mac OS X, Linux, and Solaris, which are all the OSes I have available to night to test with.
By using logname, you can assume that if the user returned by the id
command is not the same as the user returned by logname
, then the current shell session is being run under su, or sudo, or some other tool that allows for privilege change in a shell.
[[ if $LOGNAME != $USER ]]
works perfectly.
– Andrew Vit
Nov 07 '11 at 17:12
echo "$USER / $LOGNAME / $(logname)"
inside sudo -i
on my Mac OS X, I get: root / root / janmoesen
.
– janmoesen
Nov 08 '11 at 08:01
If you want to test whether the current shell was executed by su
:
[ "$(ps -o comm= $PPID)" = "su" ]
If you want to test whether the user called su
since logging in, then on many (but not all) systems you can compare LOGNAME
(normally set at the initial login) with USER
or id -un
(which identifies the current user). Note that LOGNAME
is trivially spoofable (it's an environment variable). But then, so are other solutions (for example ln -s /bin/su ~/sh; ~/sh
will hide the su
from any solution based on process names).
Here's one solution I wired up:
pstree -p $$ |
grep -oP '[r]oot su .*(\w+)' |
sed -n -E 's/.* ([[:alnum:]]+)$/\1/p'`
pstree with the -p flag lists the ancestry tree of the current shell process PID ($$)
grep finds lines containing "root su" (I'm using the [r] trick to avoid returning the grep process itself)
sed cleans up the result and prints just the current username at the end of the line. (It would be more helpful if it would print the user of the parent process though.)