Linux – Why this script in cron.daily won’t run

cronlinuxUbuntu

I wrote this small Python script to make daily backups of a directory containing some files (the backups should rotate after one week). This is it:

$ cat /etc/cron.daily/file-store-backup.py
#!/usr/bin/python3

import datetime
import calendar
import subprocess
import os.path

def main():
    origin = '/var/file-store'
    today_name = calendar.day_name[datetime.date.today().weekday()]
    dest = '/var/file-store-backup/' + today_name

    if os.path.exists(dest):
        subprocess.call(['rm', '-rf', dest])

    subprocess.call(['cp', '--reflink=always', '-a', origin, dest])
    subprocess.call(['touch', dest])

    last = open('/var/file-store-backup/LAST', 'w')
    print(today_name, file=last)

if __name__ == "__main__":
    main()

when I run it manually, it works as expected, creating a backup directory named after current week's day, but it is not being run daily: I left it inside /etc/cron.daily for 3 days and after that no backup directory was created, the server was on all time.

The permissions are right:

$ ls -l /etc/cron.daily/file-store-backup.py 
-rwxr-xr-x 1 root root 553 Abr 11 17:19 /etc/cron.daily/file-store-backup.py

The system is Ubuntu Server 12.04.2 LTS and the cron configuration was not tampered with since installation.

Why the script is not being run?

Best Answer

This is happening because your script has a .py extension. The files in /etc/cron.daily are run by the run-parts(8) command and it's default is to ignore programs that don't match various rules. You should be able to just remove the .py extension.

run-parts runs all the executable files named within constraints described below, found in directory directory. Other files and directories are silently ignored.

If neither the --lsbsysinit option nor the --regex option is given then the names must consist entirely of ASCII upper- and lower-case letters, ASCII digits, ASCII underscores, and ASCII minus-hyphens.

For example

touch /etc/cron.daily/test.py
chmod +x /etc/cron.daily/test.py
run-parts --test /etc/cron.daily
/etc/cron.daily/apache2
...

no sign of test.py

mv /etc/cron.daily/test.py /etc/cron.daily/test
run-parts --test /etc/cron.daily 
/etc/cron.daily/apache2
...
/etc/cron.daily/test

ta da !