Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
Do you really care if the login was through su or do you want to know if the current user is root? – Dason Nov 7 '11 at 2:13
No, don't care who the user is, just if it's in a su subshell. – Andrew Vit Nov 7 '11 at 2:40
up vote 5 down vote accepted

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
tk-mbp:~ tkennedy$ id -u -rn
tk-mbp:~ tkennedy$ logname
tk-mbp:~ tkennedy$ su -
tk-mbp:~ root# id -g -rn
tk-mbp:~ root# id -u -rn
tk-mbp:~ root# logname

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.

share|improve this answer
Exactly what I was looking for, thanks! – Andrew Vit Nov 7 '11 at 6:41
These are standard environment variables as well, so [[ if $LOGNAME != $USER ]] works perfectly. – Andrew Vit Nov 7 '11 at 17:12
@AndrewVit: I thought so too, but when I execute echo "$USER / $LOGNAME / $(logname)" inside sudo -i on my Mac OS X, I get: root / root / janmoesen. – janmoesen Nov 8 '11 at 8: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).

share|improve this answer
My question was just for a shell prompt so I don't need anything super robust. That test works well. Nice trick using the -o option to hide the header! – Andrew Vit Nov 8 '11 at 20:17

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.)

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.