Running CRON Jobs That Require GUI

I am using FreeFileSync utility for mirroring contents of several HDDs, call it software RAID if you must :) This software can be run in batch mode however unlike many Linux native utilities this one is not text mode by default and require more than just a terminal to run.
By any means this fact is not exceptional if you run FreeFileSync manually from some window manager, however things might not work as smoothly if you wish to run FreeFileSync at regular intervals with the help of cron for instance. That was exactly my case that I intend to describe here.

First of all I created a single script that should be called regularly by cron, the script contains all the FreeFileSync calls I need in one place. To test how the script works I added it to crontab and made it scheduled to be executed every minute:
crontab -e
cron_job_every_min
Now just to be on the safe side I restarted cron daemon:

cron_restart_and_status
Looking good, now inspecting the logs in /var/log/syslog:

cron_run_jobs

However I did not see any activity on FreeFileSync part and my disks were left unsynchronised.. What gives? What is important to know here is that cron sends you an e-mail in case it has some error to report but in order to get this mail you have to install mail server and some mail client. I went with one of the most popular choices: postfix for server with local-only configuration and mailutils package for text-based client which is called by executing mail command. Both postfix and mailutils should be available in your distro of choice, in case of Debian based flavours sudo apt-get install to the rescue!

Here is what I saw in the e-mail sent to me by cron:

mail_from_cron
It turns out the issue could be resolved with a simple trick – initialising DISPLAY variable inside the crontab itself. Here we need to remember that cron runs jobs with very limited environment and it is very common that jobs fail because of some environment variable is missing. Below I am setting the proper DISPLAY and make sure my command runs once a day instead of once per minute:

crontab_with_display
That was all I needed to successfully schedule my cron job. The takeaway is this: mind the environment working with cron, make sure to inspect syslog log and also have the local mail server properly setup in order to get mail from cron in case of issues running the jobs. By the way your inbox should be located in /var/spool/mail/ and the format of the file is human readable so maybe you won’t need mailutils, just postfix.