Why does root cron job script need 'sudo' to run properly?
Solution 1
Cron runs commands from a special shell, separate from the user or root shells. This shell does not have access to the same PATH variables as users. Therefore, when running a script as a cron job there are two options:
A. Specify the full path for every command in the script (I.e. full path to aptitude- cron doesn't know where to look to find "apt-get")
B. Little trick I use- when writing the cron job line, even in the ROOT crontab, append sudo before the script path. This will trick cron into running the script from a root shell instead of the cron shell, which will give it access to all root's PATH variables.
Solution 2
This is because the cron is running as your unprivileged user, and the apt-get
commands require root (aka administration) elevation privileges to run.
An alternative is to run this command under the root
user's crontab:
sudo -i
<type user password>
crontab -e
The first command elevates your entire shell to root and will also - crucially - give you access to root's environment, rather than just a single command as your user with elevated privileges.
The second command will edit the root crontab, not your own.
Related videos on Youtube
freejuices
Updated on September 18, 2022Comments
-
freejuices over 1 year
I'm running this simple script on my Raspberry Pi to auto update so I can forget about it. It also keeps a log that says whether the update was successful. The script is update.sh:
#!/bin/bash echo "Update starts on: $(date)" >> /home/pi/update.log if apt-get update && apt-get upgrade -y; then echo "update successful $(date)" >> /home/pi/update.log else echo "Couldn't update $(date)" >> /home/pi/update.log fi
I added this script to the root crontab by using
sudo crontab -e
and the cronjob is set to run every day at 6AM0 6 * * * /home/pi/update.sh
I know that it works to some extent because running
sudo ./update.sh
in the shell manually runs the commands and leaves a "successful" entry in the log. On the other hand, when ran from the crontab, I always get the "couldn't update" entry. In case it matters, the "update.sh" script was created by the "pi" user and I never changed the permissions, except giving it execution permissions.I read another question about the same problem and the guy solved it by putting a
sudo
in front of the command. He admits it's weird because it's already being executed by root, but says it works. I tried adding thesudo
and verified it actually works now.Does anyone know why this happens? Why does it need the
sudo
if it's already root?-
Julian over 9 yearspossible duplicate of Why does this script fail when run from cron, but works when run manually?
-
freejuices over 9 yearsI read that post and it gave a practical solution, but I don't think it gave an actual answer, not that I understood anyway. I rephrased the question to reflect that.
-
Julian over 9 yearsThe environment for sudo and pure root are not necessarily the same. try typing
env
as root and thensudo env
and compare the results. -
Kinnectus over 9 yearsIt's like Windows UAC logged in as Administrator. Although you're logged in as the admin you are still just a normal user. To run a system function you have to "ask" for an admin token that gives you the ability to perform the task. This is the same for Linux (where, I believe, the idea originated) as it prevents the user accidentally doing something daft that could potentially ruin a system.
-
Barmar over 9 yearsDoes the failing
apt-get
command report any errors? Since you're not redirecting its output, it will be sent as mail to root.
-