Perl – How To Change Output Based On Execution Context (cron or cli)

Published on Author gryzli

How to log messages based on your run environment ?

I find myself often wanting to change my output based on my running environment. Most of the times, while your script is running like cron job, you don’t want your informative messages to go to STDOUT.

One of the reasons for that, is that by default crontab sends email messages if there is output sent by the script it is executing.

 

Let say you have a perl script, which prints some informative messages, while executing. You need and want to see this messages, when you manually execute the script, but you definitely don’t want them show while executing as cron job.

I will provide two different methods which I use for differentiating between running in CRON or CLI mode.

 

  • Determining if you run as cron, by checking upon /dev/tty

The following checkIfUnderCron() function is pretty simple. It tries to open /dev/tty and if so, then we are running under CLI. If we can’t open /dev/tty, than most probably we are running as cron.

sub checkIfUnderCron {
    if ( open( my $fh_tty, "+<", "/dev/tty" ) ) {
        close($fh_tty);
        return 0;
    }
    else {
        return 1;
    }
}

 

Here is the simple usage of the function

if (checkIfUnderCron())
{
	print "We are running under cron job \n";
}else
{
	print "We are running under command line prompt \n";
}

 

  • Determining if you run as cron by using IO::Interactive – The elegant way

Perl is awesome language, which advocates some good to know practices:

There Is More Than One Way To Do It 

Don’t reinvent the wheel

In order to stick to these recommendations, we could use IO::Interactive as an alternative.

This module is pretty handy and has all we need to determine if we are running under cron or not, without the need to write our own code.

 

First we need to install the module

cpan -i IO::Interactive

 

Then we can use the following simple script

#!/usr/bin/perl
use strict;
use warnings; 
use IO::Interactive qw(is_interactive interactive busy);;


if (is_interactive())
{
	print "We are running under command line prompt \n";
}else
{
	print "We are running under cron job \n";
}

 

Also you can use directly the “interactive()” function as an argument to print. This way the function will return different file handler depending on your running mode, and if you are running in a non-interactive session (i.e. as a cron job), it will send the output to /dev/null.

#!/usr/bin/perl
use strict;
use warnings; 
use IO::Interactive qw(is_interactive interactive busy);;


print {interactive()} "This will only print if we are  running under CLI \n";

 

You can read about the other IO::Interative supplied functions: here