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