How to: Check the bash shell script is being run by root or not

by on November 12, 2007 · 22 comments· LAST UPDATED January 6, 2008

in , ,

Sometime it is necessary to find out if a shell script is being run as root user or not.

When user account created a user ID is assigned to each user. BASH shell stores the user ID in $UID variable. Your effective user ID is stored in $EUID variable. You can

Old way...

You can easily add a simple check at the start of a script:

Check the script is being run by root user

#!/bin/bash
# Init
FILE="/tmp/out.$$"
GREP="/bin/grep"
#....
# Make sure only root can run our script
if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi
# ...

New way: Using EUID

#!/bin/bash
# Init
FILE="/tmp/out.$$"
GREP="/bin/grep"
#....
# Make sure only root can run our script
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi
# ...

Mount /dev/sdb1 only if you are a root

#!/bin/bash
if [[ $EUID -ne 0 ]]; then
  echo "You must be a root user" 2>&1
  exit 1
else
  mount /dev/sdb1 /mnt/disk2
fi

Updated for accuracy and more examples.

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 22 comments… read them below or add one }

1 Jeff Schroeder November 12, 2007 at 6:52 pm

Make error messages go to STDERR (Standard Error) like they do in other Unix programs. That is the best way to do things.

if [ “$(id -u)” != “0” ]; then
echo “This script must be run as root” 2>&1
exit 1
fi

Reply

2 nixCraft November 12, 2007 at 8:37 pm

Nice suggestion, the post has been updated.

Reply

3 diana November 16, 2007 at 10:26 am

may be it was the wrong place to post this.Please help me,
I would like to send mail for each success login.i tried with this,
and place this in /root/.bashrc
#!/bin/bash
echo `last $i | head -1 | awk ‘{print $1″ “$3″ “$4″ “$5″ “$6″ “$7}’`|while read output;
do
echo $output
ip=$(echo $output | awk ‘{print $2}’ )
on=$(echo $output | awk ‘{print $3″ “$4″ “$5}’ )
at=$(echo $output | awk ‘{print $6′} )
echo “User logged in from $ip on $on at $at”|mail -s “Alert: user logged in to server $(hostname) from $ip” ephrondiana@gmail.com
done

but its sending mail for root login only,i need to send mail for users login also.Please help me…

Reply

4 Fabio January 6, 2008 at 2:07 pm

Hi,
if you want to redirect a message to stderr using echo you have to use “1>&2″ instead of “2>&1″.
For example,

~ >> f(){
> echo “to stdout” 2>&1
> echo “to stderr” 1>&2
> }
~ >> f 2>/dev/null
to stdout #this is printed to stdout
~ >>

bye

Reply

5 Terry August 11, 2008 at 9:55 pm

I think it’s worth mentioning that $UID & $EUID will not return the desired result if you use sudo to run the script, id -u does however.

Reply

6 Arky March 9, 2009 at 7:14 am

@ terry

The script works as expected.

Reply

7 Laurie April 15, 2009 at 3:14 pm

@Diana

You need to put your code into the global .bashrc file, /etc/bashrc. This will become the default .bashrc. Beware though, if you make a user specific bashrc then you need to import the global bashrc

Reply

8 gurmad November 27, 2009 at 1:29 am

Guys, please help..am a beginner to shell script and lecture gave this assingment:

1 Write a Shell script to automatically check that a specified user is logged in to the
computer.
The program should allow the person running the script to specify the name of the
user to be checked, the frequency in seconds at which the script should check. If a
checking frequency is not specified, it should default to 60 seconds
The script should check for the specified user and if found should output a message
with a “beep” or “bell” sound to the screen stating that the user is logged in. It should
also output a message to a log file stating that the user is logged in and specifying the
date and time.
If the user is not logged in the script should output a message without any “beep”
sound to the screen stating that the user is not logged in.
The script should allow a person running the script to specify the user name on the
command line and optionally, a check frequency in seconds and a third argument “q”
“q” . If “q” is present as a third argument, The script should omit any output to the
screen or “beep” sound but should log to a log file the message stating that the user is
logged in and giving the time.
The command to run the script would be as follows:
checklogin username 30 q where “checklogin” is the script name, “username” is the
name of the user, “30” is the optional frequency to check in seconds, and “q” is the
optional argument to suppress screen output.
The script should check that the number of arguments supplied is between 1 and 3 and
if it is not, should terminate with an error message showing the correct syntax for the
command.
.

Reply

9 hemanth December 14, 2009 at 5:22 am

I was using this : [[ `id -un` != root ]] && echo You must be root || mount /dev/sdb1 /mnt/disk2

Reply

10 lorenzo February 23, 2010 at 11:58 am

@hemanth

‘root’ username is not assured. It could be different. id=0 is what is used inside the kernel to identify the superuser (aka root)

Reply

11 pierreact March 15, 2010 at 8:31 am

An yet another bashism…

Reply

12 Chris March 18, 2010 at 11:00 pm

Big help, thank you!

Reply

13 jaysunn May 13, 2010 at 3:07 pm

Just used this in one of my scripts.
Thanks Vivek

Reply

14 Andreas August 19, 2010 at 8:38 pm

Typo @ last example:

echo “You must be a root user” 2>&1
exit 1

has to be

echo “You must be a root user” 1>&2
exit 1

cause you want redirect echo’s stdout to stderr (as it is also done in other examples). :-)

Reply

15 break April 14, 2011 at 6:43 am

Hello Everyone,

Firstly, great blog!

Secondly:

break@breakdown:~$ cat test.sh
#!/bin/bash

echo $EUID
id -u

break@breakdown:~$ ./test.sh
1000
1000
break@breakdown:~$ sudo ./test.sh
0
0
break@breakdown:~$ echo $EUID
1000
break@breakdown:~$ sudo echo $EUID
1000

Vivek can you explain me why last command return my normal-user EUID ? Correct me if I wrong, but “sudo ./test.sh” is executing the same command as last one (“sudo echo $EUID”) so why test.sh is returning root`s EUID ?

OS: Debian Squeeze

Reply

16 Erik August 3, 2011 at 7:26 pm

the problem with the last command is that $EUID is evaluated before sudo is executed. To get the effect you are looking for you would need to do something like:

sudo bash -c ‘echo $EUID’

Reply

17 noname April 30, 2011 at 9:27 pm

Vivek can you explain me why last command return my normal-user EUID ? Correct me if I wrong, but “sudo ./test.sh” is executing the same command as last one (“sudo echo $EUID”) so why test.sh is returning root`s EUID ?

It is clear, isnt it?

the $EUID will be examined _before_ it is processed via sudo. You pass echo 1000 to sudo, that what it does.

– me

Reply

18 @break May 4, 2011 at 7:53 am

There are differences between shells and sub shells and also when you are running some commands directly in a shell and from a bash script.

Reply

19 Kyle Fuller July 31, 2011 at 12:58 am

A simpler one-liner:
(( EUID )) && echo ‘You need to be root.’ && exit 1

Reply

20 Bob May 25, 2013 at 3:28 pm

/bin/bash is wrong here.

please use #!/usr/bin/env bash or #!/bin/sh

Reply

21 mike June 12, 2014 at 8:25 pm

Please fix this, it does not account for SUDO. $(id -u)

Reply

22 mike June 12, 2014 at 8:26 pm

I stand corrected.. I guess you have explained it in comments …

Reply

Leave a Comment

Tagged as: , , ,

Previous post:

Next post: