Perl programmer for hire: download my resume (PDF).
John Bokma's Hacking & Hiking

Running a Perl program via cron using system perl or Perlbrew

March 8, 2019

If you want to run the Perl program I wrote at regular intervals, say three times a day, you can use cron.

First, write your current crontab to a file as follows:

crontab -l >crontab.txt

If this is the first time you use cron the file might be empty. A crontab file has per entry you want to run at specific times a single line as follows:

*   *   *   *   *   command to be executed
^   ^   ^   ^   ^
|   |   |   |   |
|   |   |   |   +-- day of week (0 - 6, Sunday = 0)
|   |   |   +------ month (1 - 12)
|   |   +---------- day of month (1 - 31)
|   +-------------- hour (0 - 23)
+------------------ min (0 - 59)

The rest of this post assumes you want to run the Perl program.

Crontab with system Perl

If you installed on a system running Ubuntu and installed the required modules using apt-get you are using the system's version of Perl.

If you want to tweet automatically at, say 21:17, use the following entry:

17 21 * * * cd $HOME/twitter-tools && perl --quiet --conf john_bo
kma.conf --tweets john_bokma-tweets.txt

Note that the hour comes second and also note that this must be a single long line.

In this example the program is located in the twitter-tools directory located in the home directory.

You can activate the new crontab using:

crontab crontab.txt

Note run the above each time you change your crontab.txt.

If the program generates any output cron will email this output. However, on a default installation of Ubuntu desktop there is no Mail Transport Agent (MTA) installed and cron will log an additional message to the system log /var/log/syslog:

Mar  8 21:17:01 ecce CRON[2935]: (john) CMD (cd $HOME/twitter-tools && perl twee --dry-run --conf john_bokma.conf --tweets john_bokma-tweets.txt)
Mar  8 21:17:02 ecce CRON[2934]: (CRON) info (No MTA installed, discarding outpu

When all things work correctly, it's not really needed that the Perl program outputs any information, hence why I provided the --quiet option. But what if things don't work?

Debugging your crontab

If the program you want to run via cron doesn't work as expected, in this case no tweet is posted, how to figure out what went wrong? First, check your system's log file:

grep CRON /var/log/syslog

Does it show an entry at the time you configured? If not, you might have made a mistake I made a few times: swapped minutes and hours. Double check your cron file, remember minutes go first.

If cron complains No MTA installed, discarding output you can either install an MTA like postfix or easier, log the output to a file. To do the latter put the following after your command line in crontab.txt:

>>$HOME/cronlog.txt 2>&1

The complete entry becomes:

17 21 * * * cd $HOME/twitter-tools && perl --quiet --conf john_bo
kma.conf --tweets john_bokma-tweets.txt >>$HOME/cronlog.txt 2>&1

This creates a file in your home directory named cronlog.txt and appends (>>) both the stderr and stdout to it. Watch this file using:

tail -F cronlog.txt

Both errors and normal output should show up in this file.

If you try to run a program that has no --quiet option and unwanted output is generated you can silence it by sending the output to /dev/null, i.e. use

>/dev/null 2>&1

This discards both errors and normal output and should stop cron from complaining in the system's log about an MTA not being installed.

Crontab with Perlbrew

If you use Perlbrew things are slightly more complicated. You have to run your program via perlbrew and perlbrew needs to know the location of its home directory. This is achieved by setting the variable PERLBREW_ROOT before the call of perlbrew:

41 20 * * * cd $HOME/Amber/in-house/projects/twitter-tools && PERLBREW_ROOT=$HOM
E/.my-local/perl5 $HOME/.my-local/perl5/bin/perlbrew exec --quiet --with threade
d-perl-5.22.0 perl --quiet --conf john_bokma.conf --tweets john_bok

Note that I have my Perlbrew root in a non-standard location. Moreover, both perlbrew and the program have a --quiet option to prevent them from sending output.