0

I've got a perl script: run.pl that's been called by cron every minute.

The only thing run.pl does is call two other scripts: download.pl and parse.pl:

#!/usr/bin/perl
use warnings;
use strict;

do 'download.pl';
do 'parse.pl';
print "done!\n";

In download.pl and parse.pl are two prints to with "done downloading" and "done parsing" Now I output the script to /var/log/script.log and check for the script to run.

The run.pl script is doing fine, it outputs "done!" to the logfile. But the other two scripts aren't called. I think it is a relative path problem, it works when I use the absolute path.

But that's the problem, the script is in teststage and changes paths every time, it would be a mess to always change te absolute path.

Is there a way to let the scripts run from the relative path?

Edit: When I run it myself from the commandline with "perl run.pl" it runs the scripts without a problem.

1
  • are the other scripts always in the same directory so that './download.pl' would work? Commented Nov 8, 2010 at 16:59

3 Answers 3

5

Um, why are you using do? That doesn’t “call” a program, you know!

Are these library modules or programs?

Also, programs are expected to be found in $ENV{PATH}, whereas libraries are expected to be found in @INC. Those are almost certainly different things.

My advice is:

  1. To call another program in $ENV{PATH}, use system() or backticks.
  2. To load a library in @INC, use require or use.
  3. Reserve do FILE to exotic wizardly purposes that almost surely do not apply here.
Sign up to request clarification or add additional context in comments.

2 Comments

@Hasturkun: You hardly need quote my own writings back to me. ☹
Sorry, I must have glossed over the third paragraph
4

Cron jobs don't run with the same environment that a shell login would see. A cron job will usually have the cron's user's home directory as it's default working directory. One option to get around this is to use FindBin to locate the directory the script is in and base your paths off of that.

#!/usr/bin/perl
use warnings;
use strict;
use FindBin qw($Bin);

do $Bin.'download.pl';
do $Bin.'parse.pl';
print "done!\n";

You might be better off turning download.pl and parse.pl into real modules, it might save you some effort in the long run.

2 Comments

@tchrist, I agree, see the last sentence of my answer, but if the OP has found a rare cases where do is the right choice, then I'd argue FindBin is a good answer.
I’m something of a fan of FindBin myself, although this does get me in hot water with people whose opinions I generally respect.
0
$rootdir=`dirname "$0"`;

### call your scripts here relative to $rootdir

doesn't help?

1 Comment

Don't use a shell command when Perl provides a module that will to the same thing without the cost/security issues of using the shell. use File::Basename qw(dirname);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.