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