Programming

Gotchas with running a Perl script as a cron job

August 3rd, 2010    1 Comment

So you've written a Perl script and it runs fine from the command line using a command such as:

perl /home/alistair/scripts/myscript.pl


Great, so now you set up a cron job so that the script will run automatically. For example, let's say you want to run it every Monday morning at 4.20 am:

20 4 * * 1 perl /home/alistair/scripts/myscript.pl

 
However, when this runs it generates the following email:

Your "cron" job on myserver
perl /home/alistair/scripts/myscript.pl

produced the following output:

Can't locate DBI.pm in @INC (@INC contains: /usr/perl5/5.6.1/lib/sun4-solaris-64int /usr/perl5/5.6.1/lib /usr/perl5/site_perl/5.6.1/sun4-solaris-64int /usr/perl5/site_perl/5.6.1 /usr/perl5/site_perl /usr/perl5/vendor_perl/5.6.1/sun4-solaris-64int /usr/perl5/vendor_perl/5.6.1 /usr/perl5/vendor_perl .) at /home/alistair/scripts/myscript.pl line 15.
BEGIN failed--compilation aborted at /home/alistair/scripts/myscript.pl line 15.

 
What this means is that your script uses a Perl module (in this example, DBI.pm) which can't be found. The error message shows all the paths in the @INC list of paths where Perl looks for modules. So, for some reason, Perl found the module when you ran the script, but didn't find the module when cron ran the script as you.

The reason is that cron doesn't run in the same environment that you're using. When you connect to the server, you probably automatically change to your preferred shell (e.g. csh, ksh or bash) and load up a whole set of environment variables. This happens within the startup file – for example, .bashrc or .cshrc. But cron doesn't load up any of this, and it uses sh by default.

To see what's in @INC within your environment use this command:

perl -le 'print for grep {$_ ne q{.}and -d} @INC'

 
And you'll probably notice differences between the output you get and the contents of @INC listed in the error message.

So, to make sure @INC contains the necessary paths in any environment, load it up from within your Perl script. To do this, add something like the following to the top of your Perl script, just after the path to Perl:

BEGIN {
     push @INC,( '/usr/local/lib/perl5/5.8.2/sun4-solaris',
          '/usr/local/lib/perl5/site_perl/5.8.2/sun4-solaris',
          '/usr/local/lib/perl5/site_perl/5.8.0/sun4-solaris',
          '/usr/local/lib/perl5/site_perl/5.6.1/sun4-solaris' );
}


So now Perl will be able to find the missing Perl module. Sorted! Well maybe not.

If you now try running the script from the cron job you may get something like:

Your "cron" job on myserver
perl /home/alistair/scripts/myscript.pl

produced the following output:

ld.so.1: perl: fatal: relocation error: file /usr/local/lib/perl5/site_perl/5.8.0/sun4-solaris/auto/DBI/DBI.so: symbol Perl_PerlIO_stderr: referenced symbol not found Killed


Now it's complaining about not finding something called ld.so.1. The problem here is with your PATH.

On my server, ld.so.1 lives in /usr/lib. You should be able to find out where ld.so.1 is by running:

whereis ld.so.1


/usr/lib isn't exactly an obscure place to look, but it's not in the PATH when the cron job runs. So the easy solution is to explicitly set the contents of the PATH environment variable in the cron job:

20 4 * * 1 PATH=/usr/local/bin:/usr/bin:/usr/sbin:/usr/lib; perl /home/alistair/scripts/myscript.pl


Now, just before the Perl script is run, the PATH gets set to three paths: /usr/local/bin, /usr/bin, /usr/sbin and /usr/lib. The syntax used here is that required by the sh shell in which cron runs.

At last, job done. The script runs and you'll be emailed any output it generates.

Comments

  1. User Gravatar Bob said:

    September 1st, 2010 at 2:58 pm (#)

    This is an extremely helpful post. It's a relief to finally have an explanation for all the problems I've had with cron and Perl. But it confirms for me that two should never be used together. There are just far too many headaches. My Ubuntu system doesn't even produce the error you show at the top of the post, leaving the poor user completely in the dark regarding why the script isn't running. Pure rubbish.

Leave a comment

 

PHP (or Perl) one line if/then/else statements

August 8th, 2009

If you're toggling something between two states in PHP or Perl it's often handy to use an if/then/else one liner.

In pseudocode this goes like this:

<if this evaluates to TRUE> then <parse this> else <parse this>

All you need to do is replace the "then" with a question mark and the "else" with a colon:

<if this evaluates to TRUE> ? <parse this> : <parse this>

For example:

print  $trueOrFalse ? "you're telling the truth" : "you're lying";

Ignore the print command, it's not part of the if/then/else statement, it's just here to do something with the outcome of that statement.

The expression immediately to the left of the question mark is evaluated. The expression between the question mark and the colon is parsed if the expression evaluates to TRUE, otherwise the expression immediately to the right of the colon is parsed. So in the above example, either "you're telling the truth" or "you're lying" is printed, depending on whether $trueOrFalse is ... you guessed it ... TRUE or FALSE.

But perhaps a more common situation is toggling the value assigned to a variable. For example, toggling between TRUE and FALSE:

$trueOrFalse = $trueOrFalse ? FALSE : TRUE;

Here's a practical example of the use of if/then/else one liners. There's two in this chunk of PHP. The scroll box list below the code is the kind of thing this PHP produces.

<div style="overflow:auto; height:100px; width:300px; border:3px groove #DDD; padding:0">
<?php
    $alternateLine = FALSE;
    while($presidentsArray) {
        print "<div style=\"background-color:";
        print $alternateLine ? "#F5F8F9" : "white";
        print "; padding-bottom: 1px\"> &nbsp; &nbsp; <a href=\"someURL\" title=\"This link goes nowhere\">" .
          $presidentsArray['name'] . "</a></div>";
        $alternateLine = $alternateLine ? FALSE : TRUE;
    }
?>
</div>

Leave a comment



A handy PHP date() checker

July 30th, 2009

A handy site to remember if you’re writing PHP is http://php-date.com/. It provides everything you need to know about the date() function in PHP and has an interactive form for testing your formatting until you get your dates/times just the way you want them.

php-date-function

Potentially similar posts

Leave a comment



“Programmers love hierarchy … normal people hate that”

March 15th, 2009    4 Comments

treeviewSomething I’ve been preaching for years, to any software developer who’ll listen, is: don’t use a tree view control in the user interface if your users are not highly technical and there’s another way of allowing the user to do the thing they actually want to do (which there usually is if you put some thought into it).

So I was delighted to hear Jeff Atwood and Joel Spolsky’s views on the Stack Overflow Podcast #45:

 


Atwood:   … programmers love hierarchy, to a degree that they don't even understand how different they are than the public in this regard. Like they love putting everything in this little bucket, that goes in this little bucket, which is this sub-bucket of this and this, and normal people hate that. And threading is totally a manifestation of that and it drives me crazy that a lot of programmers can't see that they're like immediately like: "Oh, threading is good. I love threading. What are you talking about?" You know? They can't see it at all.

Spolsky:   Right, right.

Atwood:   It's like myopia.

Spolsky:   Yeh. I mean it's really a function of the size of the group, and one thing I've learned through years and years of usability testing is that anything that smacks of a hierarchy or a tree is not going to be understandable to the average, non-technical user.

Atwood:   Yeh.

Spolsky:   You just have to learn that: if it's a tree, or a hierarchy, like eighty per cent of the regular people are going to get confused and not quite get it.


Hierarchies are great at showing nested relationships, and they make sense to programmers, who are used to them – but most of the time the relationships don’t matter to the user. Usually the user just wants to find something and yet the tree view forces them to “drill down”, clicking down into a hierarchy that becomes increasingly complex as they click.

My request to all programmers placed in the position of having to design a user interface: avoid hierarchies unless you truly believe the end users really need the hierarchical information.

Leave a comment



Stack Overflow virgin

February 26th, 2009

stackoverflow-logo-250 I posted my first question on Stack Overflow today and already it’s had a couple of replies. I can see how Stack Overflow could become a little addictive because it has elements of a game built into it. For starters, you build up reputation points, which you get from other people by providing answers, but you need some reputation points before you can start giving points to others, and you can’t comment on other people’s answers until you’re above a certain rep level.

Have a listen to Hanselminutes Show 134 to hear Jeff Atwood, CEO of Stack Overflow, talking about the concept of the site and what they’ve done to make it an appealing place for software developers to hang out. The bit that really struck a chord with me was when he described Stack Overflow as sort of an antidote to Experts’ Exchange, the latter being a site that really rubs me up the wrong way because of its underhand tactics. There are so many times I’ve searched for something technical on Google and found a hit that looks like it might provide the answer I was looking for but I don’t notice it’s at Experts’ Exchange until I get there and discover the details are obscured because the site is run as a private club, which I refuse to join.

I like Stack Overflow. The only thing I don’t like about it is that I think its search facility is very weak right now. If you want to find stuff it’s best to use Google, like this:

http://www.google.com/search?q=site:stackoverflow.com/questions YOUR QUERY

For example:

http://www.google.com/search?q=site:stackoverflow.com/questions online help

The other aspect of it is that, if you’re not a programmer – or even if you are – it can be an intimidating place for the newcomer. You have to brace yourself and be prepared to be told you’re an idiot and should go away and never darken the doors of Stack Overflow again. But, in some ways, that’s not altogether a bad thing. It’s intended to be a games room for professional programmers – it’s not designed for just anybody to go and find an answer to any old thing. But, unlike Experts’ Exchange, everyone’s allowed to come in and wander around and listen in on the conversations. However, if you try answering a question you’re not qualified to answer, or you start asking questions that should have been asked elsewhere, then you can expect the regulars to give you a hard time.

Leave a comment



^ back to top ^

Page 1 of 3123