quadmore
quadmore

Reputation: 1331

Identify user in a Bash script called by sudo

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?

Upvotes: 133

Views: 70593

Answers (9)

Seamus
Seamus

Reputation: 223

This answer is intended to be a sort-of-compendium of some of the other answers here. If you're interested, I found this Q&A in this search.

The headline Question is:

Identify user in a Bash script called by sudo

AIU the Question posed by the OP, he wants to get at the name of the "logged-in-user" who started a script using sudo myscript.

Several of the answers here worked for me - on my system (Debian 'bookworm'), but judging from some of the comments, some that worked on my system did not work for others. I built a simple script that might be useful to others, so I'm adding it here:

#!/usr/bin/env bash
# my $0 is tstr.sh
echo -e "'whoami' ===> $(whoami)"
echo -e "'who am i' ===> $(who am i)"
echo -e "'echo \$SUDO_USER' ===> $SUDO_USER"
echo -e "'logname' ===> $(logname)"

You can run this as a regular user, under sudo tstr.sh, from sudo su -, from sudo -i, etc, etc:

$ sudo tstr.sh
'whoami' ===> root
'who am i' ===> seamus       pts/2        2024-11-18 06:12 (192.168.1.209)
'echo $SUDO_USER' ===> seamus
'echo $(logname)' ===> seamus

$ sudo su -
root@sys3a:~# cd /home/seamus && ./tstr.sh
'whoami' ===> root
'who am i' ===> seamus       pts/2        2024-11-18 06:16 (192.168.1.209)
'echo $SUDO_USER' ===>
'logname' ===> seamus

$ exit && sudo -i && cd /home/seamus && ./tstr.sh
'whoami' ===> root
'who am i' ===> seamus       pts/2        2024-11-18 06:18 (192.168.1.209)
'echo $SUDO_USER' ===> seamus
'logname' ===> seamus

It seems that logname is the most consistent answer to the Question. who am i strikes me as a potentially troublesome answer b/c it winds up spawning another pts to get the correct answer. This may create other issues depending on the requirements of the script in use, and there's no system manual for it.

Upvotes: 1

B H
B H

Reputation: 121

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.

Upvotes: -1

Jim Hunziker
Jim Hunziker

Reputation: 15380

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

LOCAL_USER_ID=$(id -u $(logname))

Upvotes: 5

Rob
Rob

Reputation: 81

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

Upvotes: 8

Brandon Horsley
Brandon Horsley

Reputation: 8104

I think $SUDO_USER is valid.

#!/bin/bash
echo $SUDO_USER
whoami

Upvotes: 68

Srinivas
Srinivas

Reputation: 177

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

Upvotes: 2

Alexei Tenitski
Alexei Tenitski

Reputation: 9360

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`

Upvotes: 15

evan
evan

Reputation: 12535

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

Upvotes: 172

msw
msw

Reputation: 43497

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

Upvotes: 1

Related Questions