Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop being root in the middle of a script that was run with sudo

There is a list of commands that only succeed when they are prefaced with sudo.
There is another list of commands that only succeed when the user runs them without sudo.

I want to execute all of these commands from the same script.
I'd like to avoid having to do the following:

#!/usr/bin/env bash
sudo sudo_command_one;
sudo sudo_command_two;
sudo sudo_command_three;
non_sudo_command;
sudo sudo_command_four;

The reason for this, is because sudo has a time-out, and these commands will likely take a long time. I don't want to be burdened with having to re-type the sudo password occasionally. I could perhaps extend the time-out of sudo indefinitely, but that is also something I would prefer to avoid if there is an easier way.

Therefore, I'm going to run the script like this:

sudo ./script

But this will prevent the non-sudo commands from working.
What are the missing commands I need:

#!/usr/bin/env bash
sudo_command_one;
sudo_command_two;
sudo_command_three;
[turn sudo off for a moment]
non_sudo_command;
[ok, turn sudo back on]
sudo_command_four;

Unfortunately, the order of the commands cannot be rearranged so that I run all the sudo commands first, followed by all the non-sudo commands(or vice versa).

like image 326
Trevor Hickey Avatar asked Feb 11 '23 05:02

Trevor Hickey


2 Answers

In a script run by sudo, use:

su -c "shell command; shell command" $SUDO_USER 

within that script to execute commands as the normal user who invoked sudo.

This works because sudo sets the environment variable SUDO_USER to the original username.

If you have a bunch of commands to run as the original user, you could use a hereis document.

Here is an example script file as proof of concept:

myscript.sh

#!/bin/bash
echo "Part 1"
echo "now running as:"
whoami
echo "SUDO_USER is:"
echo $SUDO_USER
su $SUDO_USER <<EOF
echo "Part 2"
echo "now running as:"
whoami
echo "SUDO_USER is:"
env | grep ^SUDO_USER
sleep 5
EOF
echo "Part 3"
echo "now running as:"
whoami
echo "SUDO_USER is:"
echo $SUDO_USER

And here's the output on sudo ./myscript.sh

Part 1
now running as:
root
SUDO_USER is:
paul
Part 2
now running as:
paul
SUDO_USER is:
SUDO_USER=paul
Part 3
now running as:
root
SUDO_USER is:
paul

Warning: This technique doesn't work so well with nested sudo. If sudo is nested twice, e.g.

sudo su

echo $SUDO_USER
---> me

sudo su
echo $SUDO_USER
---> root

SUDO_USER will return root, not the original username. su $SUDO_USER would then keep running as root. Be careful to avoid that scenario, and it should work ok.

like image 65
Paul Avatar answered Feb 13 '23 21:02

Paul


Here is how I would run it in a script.

#! /bin/bash

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root";
   exit 1;
else
    NON_ROOT_USER=$(who am i | awk '{print $1}');
    echo "root ran this echo.";
    sudo -u $NON_ROOT_USER echo "$NON_ROOT_USER ran this echo.";
fi

sudo ./script.sh

like image 42
almyz125 Avatar answered Feb 13 '23 21:02

almyz125