How to stop a script from running if it's not root (and echo "Not running as root! Exiting...")

#!/bin/sh

if [ "$(id -u)" -ne 0 ]; then
        echo 'This script must be run by root' >&2
        exit 1
fi

cat <<HEADER
Host:          $(hostname)
Time at start: $(date)

Running cache maintenance...
HEADER

swapoff -a && swapon -a
echo 1 >/proc/sys/vm/drop_caches

cat <<FOOTER
Cache maintenance done.
Time at end:   $(date)
FOOTER

The root user has UID 0 (regardless of the name of the "root" account). If the effective UID returned by id -u is not zero, the user is not executing the script with root privileges. Use id -ru to test against the real ID (the UID of the user invoking the script).

Don't use $EUID in the script as this may be modified by an unprivileged user:

$ bash -c 'echo $EUID'
1000

$ EUID=0 bash -c 'echo $EUID'
0

If a user did this, it would obviously not lead to privilegie escalation, but may lead to commands in the script not being able to do what they are supposed to do and files being created with the wrong owner etc.


I think what you want is rather to check that you have super-user privileges, that is, that your effective user id is 0.

zsh and bash make that available in the $EUID variable, so you can do:

if ((EUID != 0)); then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

With any POSIX-like shells, you can use the id standard command:

if [ "$(id -u)" -ne 0 ]; then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

Note that all of id -un or whoami or the $USERNAME variable in zsh will get you the first username for the uid. On systems that have other users with id 0, that may not be root even if the process is a descendant of one that has been authenticated as root.

$USER would usually give you the user that authenticated, but relying on it is quite brittle. It's not set by the shell, but is usually set by the authenticating command (like login, su (on GNU/Linux systems, not necessarily others), sudo, sshd (the one from openssh at least)...). It's not always though (changing the uid does not automagically set that variable, it has to be done explicitly by the application changing the uid) and it could also have been modified by some other process in the shell's ancestry. $LOGNAME, with the same caveat is more reliable as it's specified by POSIX (originally from FIPS 151-2)


You can use $USER or whoami to check the current user.

if [[ "$USER" != "root" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

if [[ $(whoami) != "root" ]]; then
    echo "Warning: script must be run as root or with elevated privileges!"
    exit 1
fi

if [[ $(id -u) != "0" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi