How can a script check if it's being run as root?

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?


Solution 1:

#!/bin/bash
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 
   exit 1
fi

Solution 2:

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

Solution 3:

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

Solution 4:

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' ]

Solution 5:

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)"))
}