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 tweetfile.pl 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 tweetfile.pl Perl program.

Crontab with system Perl

If you installed tweetfile.pl 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 tweetfile.pl --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 tweetfile.pl 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 tweetfile.pl 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
tfile.pl --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
t)

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 tweetfile.pl --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 tweetfile.pl --quiet --conf john_bokma.conf --tweets john_bok
ma-tweets.txt

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

Related