"apt-get -y upgrade" in cron task runs but does not upgrade the system

Solution 1:

It seems I found the cause of the problem.

To detect the error, I had to catch stderr in my custom log. It turned out it was useful to do that because some errors were not mailed to root and weren't written in other logs either.

To catch stderr in my log, I first changed the cron task to:

52 15 * * * apt-get -y upgrade >> /var/log/my-apt-upgrade.txt 2>&1

Today the package "wlibgcrypt11" was to be updated. This time, my log caught an error. It was more explicit than the vague error message that had appeared earlier in /var/log/apt/history.log.

In /var/log/my-apt-upgrade.txt today:

Reading package lists...
Building dependency tree...
Reading state information...
The following packages will be upgraded:
  libgcrypt11
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin: 
1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/300 kB of archives.
After this operation, 35.8 kB of additional disk space will be used.
dpkg: warning: 'ldconfig' not found in PATH or not executable
dpkg: warning: 'start-stop-daemon' not found in PATH or not executable
dpkg: error: 2 expected programs not found in PATH or not executable
Note: root's PATH should usually contain /usr/local/sbin, /usr/sbin and /sbin
E: Sub-process /usr/bin/dpkg returned an error code (2)

So it was a PATH error.

The root's PATH on my system contains all the required directories. So does the secure_path variable in visudo. That's why everything works when I run sudo apt-get manually.

But cron doesn't set the environment variables. So I added a PATH environment variable for each of the cron tasks.

$ sudo crontab -e

22 16 * * * PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' apt-get -y update >> /var/log/my-new-apt-update.txt 2>&1
32 16 * * * PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' apt-get -y upgrade >> /var/log/my-new-apt-upgrade.txt 2>&1

And it worked! The package was successfully updated by the cron task.