20

This question already has an answer here:

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?

marked as duplicate by muru, Thomas Dickey, Satō Katsura, Tobias Kienzler, terdon shell-script Mar 23 '17 at 10:00

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 7
    The usual way is to run the script as the invoking user and use sudo for those commands which needs it. sudo caches the credentials, so it should prompt at most once. – AlexP Mar 22 '17 at 23:35
  • 9
    Yes, it's called "switch user and do", or sudo for short. – immibis Mar 23 '17 at 0:07
  • 15
    Reverse sudo? You mean, sudont? – Beanluc Mar 23 '17 at 0:45
  • 9
    I tried "odus", but it didn't do anything. – HopelessN00b Mar 23 '17 at 3:04
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.

  • 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. – hexafraction Mar 23 '17 at 0:33
28

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
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
2

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.