Why does root cron job script need 'sudo' to run properly?

16,108

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.

Share:
16,108

Related videos on Youtube

freejuices
Author by

freejuices

Updated on September 18, 2022

Comments

  • freejuices
    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 6AM

    0 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 the sudo and verified it actually works now.

    Does anyone know why this happens? Why does it need the sudo if it's already root?

    • Julian
      Julian over 9 years
    • freejuices
      freejuices over 9 years
      I 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
      Julian over 9 years
      The environment for sudo and pure root are not necessarily the same. try typing env as root and then sudo env and compare the results.
    • Kinnectus
      Kinnectus over 9 years
      It'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
      Barmar over 9 years
      Does the failing apt-get command report any errors? Since you're not redirecting its output, it will be sent as mail to root.