22

Let's say I have a script that will be executed on various machines with root privileges, but I want to execute certain commands within that script without root.

Is that possible?

Maxim
  • 728

4 Answers4

34

Both su and sudo can do this. They run a command as another user; by default that "another user" is root, but it can be any user. For example,

sudo -u www-data ls

will run ls as the user www-data.


However...

The usual way is to run the script as the invoking user and use sudo for those commands which need it. sudo caches the credentials, so it should prompt at most once.

AlexP
  • 10,455
  • 7
    sudo will only cache the credentials for a limited time; if the script spends enough time executing non-root commands these cached credentials may be lost. – nanofarad Mar 23 '17 at 00:33
31

sudo exports environment variables SUDO_COMMAND, SUDO_GID, SUDO_UID, and SUDO_USER.

You can use SUDO_USER or SUDO_UID to get back to the invoking user:

sudo -u "$SUDO_USER" an_unprivileged_command
Petr Skocik
  • 28,816
4

sudo is a souped-up version of su with better access controls. If you're already running as root, su will do it with no fuss:

#!/bin/sh -e
echo -n "Script User:          " && id -un
echo -n "Other user:           " && su blrfl -c "id -un"
echo -n "Back to script user:  " && id -un

When run, you get this:

Script User:          root
Other user:           blrfl
Back to script user:  root
Blrfl
  • 384
3

I agree with AlexP’s answer that you should generally run as non-root and only invoke sudo only for commands that need it. Whitelisting is always safer than blacklisting.

In addition to AlexP’s answer: You might want to invoke sudo at the very top of the script, to make sure that you don’t execute a number of operations until you realize that the user isn’t permitted to run sudo, and create a broken state. Therefore, I recommend to put the following at the top of scripts which need sudo at some point:

#!/bin/bash

sudo true || exit 1

# … other code …

This will immediately ask for the password (if necessary) and abort executing the script if sudo fails.

lxg
  • 149