Personally I believe if you aren't looking at the script before you run it, whatever side effects that happen are mostly your fault (commands running with
sudo that don't prompt you for example), but at the same time, I know it can be hard to parse and grok an entire script every time. Overall I prefer a hybrid strategy where I can balance convenience and security.
Keep in mind you can always run
sudo -k before calling a script to require the first implicit
sudo call to prompt for your password, though unless it also is run after every
sudo command inside the script it will ONLY prompt you for the very first call to
There are a few ways to accomplish a safe, sane script using sudo only when necessary, some more icky/ill-advised than others. This post outlines a few examples/options that I will expand upon further. https://bitmingw.com/2017/01/22/use-sudo-in-scripts/
You can run the whole script with
sudo which as you described is "explicit", but this also means ALL the commands within the script run as root, and if it isn't well written or you forgot that
$USER might change inside the script to
root and you instead needed to use
$SUDO_USER then you could end up in a world of hurt. I've accidentally done this in the past and weird and terrible things happened and then you (and I) end up guarding your scripts with
if [ $EUID -eq 0 ]; then echo "Don't run as root!"; fi or the opposite
-gt 0 and you have to remember to put one of the guards in every script you write (or learn configuration management tools like SaltStack/Puppet/Chef that can automate some of this for you).
The option I prefer to use is to run TEMPORARILY run
sudo with an infinite cache time so no other sudo commands run by you require a re-prompt (or possibly anybody depending on how you set it up). Ideally you would put a properly automated and tested function (or include your "cache_sudo.sh" script) early in your scripts and then remove the infinite timeout enabling
sudoers.d file as soon as the script exits (killed/finished/error) using
trap and then
sudo -k to expire the session/token after removing the file. See this answer for a example of testing and add the file only if valid.
This is the manual version, don't put this into your script.
sudo visudo -f /etc/sudoers.d/infinite_cache_myuser
#Add next line to the file
The benefits of the infinite cache is within your script you can elevate ONLY the commands that require root with sudo, while not having to "downgrade" ALL the other commands using
su $MY_REGULAR_USER some_command or
sudo -u $MY_REGULAR_USER some_command for EVERY SINGLE command. (I really dislike pointlessly repeated code to drop privileges if there is a less painful and not totally insecure way to write it to only elevate when necessary).
One way to lessen the repeated code would be define a short command "prefix" that adds
su $MY_USER depending on whether the script will be run with
sudo ./myscript.sh or
You could write a
sudoers rule to allow executing the target script with
sudo and no password prompt but I think this is just as bad an idea as the first option, it only helps slightly if you want to run sudo from a cron job that runs as a non-root user but needs to alter something that requires root or another user, though you'll need to read
man sudoers to learn the syntax for allowing a user to impersonate another user.
# Customize line below and add to /etc/sudoers or /etc/sudoers.d/my_script_runner
YOUR_USER_NAME ALL=(ALL:ALL) NOPASSWD:/abs/path/to/your/script
You can also allow passwordless sudo for only the commands that require it, which allows you to run the script as non-root and still access those commands.
YOUR_USER_NAME ALL=(ALL:ALL) NOPASSWD:/usr/bin/apt-get update
YOUR_USER_NAME ALL=(ALL:ALL) NOPASSWD:/usr/bin/apt-get upgrade
YOUR_USER_NAME ALL=(ALL:ALL) NOPASSWD:/usr/bin/updatedb
This option is probably my second choice behind the infinite cache trick. The downside is you are editing the sudoers file every time you find a new command that needs root, rather than just being able to add
sudo in front of the command in your script. The upside is you are only allowing passwordless
sudo when necessary, and you can still require a password for other
sudo commands thus staying much safer.