171

I'm writing a simple bash script, but I need it to check whether it's being run as root or not. I know there's probably a very simple way to do that, but I have no idea how.

Just to be clear:
What's a simple way to write a script foo.sh, so that the command ./foo.sh outputs 0, and the command sudo ./foo.sh outputs 1?

Malabarba
  • 10,546

11 Answers11

230
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 
   exit 1
fi
aneeshep
  • 30,949
155

A root user does not have to be named "root". whoami returns the first username with user ID 0. $USER contains the name of the logged in user, which can have user ID 0, but have a different name.

The only reliable program to check whether the account is logged in as root, or not:

id -u

I use -u for the effective user ID, not -r for the real user ID. Permissions are determined by the effective user ID, not the real one.

Tests

/etc/passwd contains the following usernames with user ID 0 in the given order:

rootx
root2

Logged in as root2, gives the next results:

  • whoami: rootx
  • echo $USER: root2 (this returns an empty string if the program was started in an empty environment, e.g. env -i sh -c 'echo $USER')
  • id -u: 0 As you can see, the other programs failed in this check, only id -u passed.

The updated script would looks like this:

#!/bin/bash
if ! [ $(id -u) = 0 ]; then
   echo "I am not root!"
   exit 1
fi
Lekensteyn
  • 178,446
40

As @Lekensteyn said you should use effective user ID. You don't need to call id -u in bash:

#!/bin/bash

if [[ $EUID -ne 0 ]]; then
   echo "You must be root to do this." 1>&2
   exit 100
fi

@geirha's suggestion from the comments uses arithmetic evaluation:

#!/bin/bash

if (( EUID != 0 )); then
   echo "You must be root to do this." 1>&2
   exit 100
fi
jfs
  • 4,078
21

You can accomplish this by using the whoami command, which returns the current user:

#!/bin/bash

if [ `whoami` != 'root' ]
  then
    echo "You must be root to do this."
    exit
fi

...

Running the above will print You must be root to do this. if the current user is not root.


Note: an alternative in some cases is to simply check the $USER variable:

if [ $USER != 'root' ]
Nathan Osman
  • 32,495
13

Taking efficiency into consideration, you may test, first, the EUID environment variable and then, if it doesn't exist, call the standard id command:

if ((${EUID:-0} || "$(id -u)")); then
  echo You are not root.
else
  echo Hello, root.
fi

This way, because of the OR shortcut, you avoid calling a system command, prioritizing the query of an in-memory variable.

Code reuse:

function amIRoot() {
  ! ((${EUID:-0} || "$(id -u)"))
}
10
#!/bin/bash
[[ $(id -u) != 0 ]] 
echo $?
João Pinto
  • 17,323
3
#!/bin/bash
if [ "$(id -u)" == "0" ]
then
    echo "I am root."
else
    echo "I am not root."
fi
2

This snippet would:

  • Check on different sessions
  • suggest to use sudo !!
  • and return an error
if [ "$(whoami &2>/dev/null)" != "root" ] && [ "$(id -un &2>/dev/null)" != "root" ]
      then
      echo "You must be root to run this script!"
      echo "use 'sudo !!'"
      exit 1
fi
rubo77
  • 34,024
  • 52
  • 172
  • 299
2

This answer is just to save an idea with may be helpful for some of you. If you need script which is run from desktop GUI and requires root privileges try this way:

#!/bin/bash
if ! [ $(id -u) = 0 ]; then
   gksudo -w $0 $@
   exit
fi

#here go superuser commands, e.g. (switch intel cpu into powersave mode):
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
cpupower frequency-set -g powersave

This way you will get nice dialog window asking you for root user password. Just like with command-line sudo.

The gksudo may not be available in your system then install it with sudo apt-get install gksu.

gertas
  • 139
2

One simple way to make the script only runnable by root is to start the script with the line:
#!/bin/su root

1

This code works under both Bash and stock Bourne sh (tested under FreeBSD) that does not define EUID. If EUID exists its value is returned, else the 'id' command is run. It is a tad shorter than the "or" example above, as it uses a shell built-in ":-".

Root in sh:

# echo $EUID

# euid=${EUID:-`id -u`}
# echo $euid
0

In bash:
[chaapala@tenfwd2 ese]$ euid=${EUID:-`id -u`}
[chaapala@tenfwd2 ese]$ echo $euid
10260