Sudo in Shell Script – Running Non-Interactive Scripts

shell-scriptsudo

I have a script that executes three functions: A && B && C.

Function B needs to be run as a super-user, while A and C don't.

I have several solutions but neither of these are satisfying:

  1. sudo the entire script: sudo 'A && B && C'

    That seems like a bad idea to run A and C as super-user if it's not
    needed

  2. make the script interactive: A && sudo B && C

    I might have to type-in my password, but I want my script to be
    non-interactive, as each function can take some time, and I don't want
    the script to wait for me. Well, that's also why it's a script in the
    first place, so I don't have to watch it run.

  3. The stupid solution: sudo : && A && sudo -n B && C

    First it seems stupid to run a no-op sudo first, and also I must cross
    my finger that A is not going to take more than $sudo_timeout.

  4. Hypothetical solution (I wish you tell me it exists):

    sudo --store-cred 'A && sudo --use-cred-from-parent-sudo B && C'

    That would prompt for my password at the beginning, and then use that
    credentials only when needed.

What's your opinion on all this? I'd be very surprised that there is no
solution to that problem, as I think it's a pretty common problem (what
about make all && sudo make install)

Best Answer

I think the best thing that you can do is launch the script with sudo and then launch the processes you want to run as a normal user explicitly with su user or sudo -u user:

#!/usr/bin/env bash

## Detect the user who launched the script
usr=$(env | grep SUDO_USER | cut -d= -f 2)

## Exit if the script was not launched by root or through sudo
if [ -z $usr ] && [ $UID -ne 0 ]
then
    echo "The script needs to run as root" && exit 1
fi

## Run the job(s) that don't need root
sudo -u $usr commandA

## Run the job that needs to be run as root
commandB
Related Question