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.