Identify user in a Bash script called by sudo
Asked Answered
J

8

131

If I create the script /root/bin/whoami.sh containing:

#!/bin/bash
whoami

and this script is called by a user with a properly configured sudo, it will indicate

root

Is there a fast way to obtain the actual user in a script, or will I have to resort to parameters passing along this username?

Jaine answered 19/8, 2010 at 13:38 Comment(0)
M
169

$SUDO_USER doesn't work if you are using sudo su -.
It also requires multiple checks - if $USER == 'root' then get $SUDO_USER.

Instead of the command whoami use who am i. This runs the who command filtered for the current session. It gives you more info than you need. So, do this to get just the user:

who am i | awk '{print $1}'

Alternatively (and simpler) you can use logname. It does the same thing as the above statement.

This gives you the username that logged in to the session.

These work regardless of sudo or sudo su [whatever]. It also works regardless of how many times su and sudo are called.

Mcgann answered 4/1, 2011 at 20:10 Comment(10)
Alternative to who am i is who mom likes. Your choice.Parsee
who returns 2 lines for me, both containing my name, and who am i returns none. Any help?Erythrism
I notice that this doesn't work in a docker container, as the who am i seems to depend on login and thus returns blank. Try docker run -it ubuntu bash, and whoami gives the user (root in this case, but works correctly with alternate users), while who am i is blank.Frecklefaced
Thanks, I'm using owner() { ls -ld $1 | awk '{print $3}'; } in my script to get the owner string; usage: if [ "$(owner $file)" != $(logname) ]Tailspin
I'm on Ubuntu 16.04 and the command who am i does nothing, it seems to be simply who, so who | awk '{print $1}' works as expected ;)Habitude
Just incase you don't have awk installed, you can also use cut: who mom likes | cut -d' ' -f1 or sed for some reason: who mom likes | sed -n 's/^\([^ ]*\).*/\1/p'Gob
I have question. If I have the following script : 1 #~/bin/bash 2 3 USERNAME=who am i` 4 5 echo "$USERNAME" ` ~ and if I execute sed -n 5p ./second.sh | sudo bash and on the terminal "root" is printed instead of the user with whom I execute this command?Glyphography
Note: logname doesn't work when you run it from a terminal window because it's a non-login terminal.Unbeknown
Interestingly who returns my graphical and numerous (tmux) sessions, while who am i returns only the current session where I am running the command. This could get interesting where you might need a head -1 or to try who am i if you see more than $# = 1 lines in the first return. If I run a script as another user that has sudo permissions to a specific path that is NOT my primary login user (say a service account that needs to run eg nginx with sudo to grab port 80) I'm not sure what it will return.Hessney
@daveoncode: your approach works if your current user was the first to log in... https://mcmap.net/q/172970/-identify-user-in-a-bash-script-called-by-sudo seems to work in all casesChristachristabel
C
67

I think $SUDO_USER is valid.

#!/bin/bash
echo $SUDO_USER
whoami
Cardiac answered 19/8, 2010 at 13:45 Comment(6)
Strange thing: sudo env shows SUDO_USER but sudo echo $SUDO_USER prints nothing...Gramarye
job, this is not strange, it's expected. in sudo echo $SUDO_USER, bash is evaluating $SUDO_USER before executing sudo. try the script posted in this solution, it works.Kwakiutl
@quadmore: If you're happy with the answer, don't forget to accept it.Gramarye
You could also use echo ${SUDO_USER:-$USER} to catch both sudo and non-sudo running. But evan's answer logname sounds easerFryd
@TobiasKienzler - And as evan points out, $SUDO_USER doesn't work with sudo su -, but logname always works.Erleena
sudo sh -c "echo \$SUDO_USER"Eared
B
15

Here is how to get the username of the person who called the script no matter if sudo or not:

if [ $SUDO_USER ]; then user=$SUDO_USER; else user=`whoami`; fi

or a shorter version

[ $SUDO_USER ] && user=$SUDO_USER || user=`whoami`
Blakney answered 20/1, 2013 at 21:9 Comment(1)
even shorter: user=${SUDO_USER:-$(whoami)} or user=$(logname)Fryd
M
8

Using whoami, who am i, who, id or $SUDO_USER isn't right here.

Actually, who is never a solution to the question, as it will only list the logged in users, which might be dozens...

In my eyes, the only valuable answer is the use of logname.

Hope this helps

Rob

Martymartyn answered 4/8, 2019 at 22:47 Comment(0)
S
5

If it's the UID you're looking for (useful for docker shenanigans), then this works:

LOCAL_USER_ID=$(id -u $(logname))
Seena answered 11/9, 2019 at 13:10 Comment(0)
H
2

who am i | awk '{print $1}' didn't work for me but who|awk '{print $1}' will serve the job

Headpiece answered 22/5, 2017 at 10:58 Comment(3)
Not on a host where more than one user has sessionSubtropics
It's whoami all one word, not who am i. This follows typical structure where shell commands typically are a single word, with arguments following. who am i would be interpereted as running the command who with the arguments of am and i. who just so happens to also be a command, but it outputs more than is needed in this case, whereas whoami just prints the username.Materials
@EliSmith whoami doesn't solve the problem, because it doesn't look for the caller via root.Madelene
F
1

Odd, the system does distinguish between real and effective UIDs, but I can find no program that exports this at shell level.

Flagella answered 19/8, 2010 at 13:49 Comment(0)
M
0

Having the same question, using Rocky Linux 9.2, I ran this script:

#!/bin/bash
echo "LOGNAME: $LOGNAME"
echo "SUDO_USER: $SUDO_USER"
set | grep username

in each of these scenarios:

  • as user (./script.sh)

    • LOGNAME: username
    • SUDO_USER: null
  • as root via sudo (sudo ./script.sh)

    • LOGNAME: root
    • SUDO_USER: username
  • as root via su (./script.sh)

    • LOGNAME: username
    • SUDO_USER: null
  • as root via sudo su (./script.sh)

    • LOGNAME: root
    • SUDO_USER: username

Using an if...then...else check would work, unless you inadvertently sudo run the script while you are already at the superuser prompt:

#root: sudo ./script.sh
  • via either su or sudo su the results are
    • LOGNAME: root
    • SUDO_USER: root

However, one set variable has proven to be consistent though all of my scenarios:

MAIL=/var/spool/mail/username

I now set the logged in user as:

UNAME=$(echo $MAIL |cut -d/ -f5)

I'm sure there are situations where this would not work, but I haven't found one yet.

Melodie answered 1/6, 2023 at 13:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.