Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm having a little issue reading a file into my perl scripts while using cron. I have a small text file that stores two lines of text. I have a perl script that needs to read in this text. Here's the code I use:
open(TICKS,"textfile"); while(<TICK>){ $thestring=$_; } print $thestring;
I have my perl script execute automatically each night using cron. However, whenever cron runs the script, it never is able to read in the text from the file. No errors are reported, the file is just read. Each night I check my computer to find that the script has not read the file. I then manuall run the script and it reads the file just fine.

I having trouble determining what is wrong. Could this be a permissions issue. Cron is run as root, right? When I run the script manually it is as root as well. Is it possible that running the script a second time successively does the trick? If I run the script manually after cron runs it, it reads the text file fine even though it didn't when run through cron.

Thoughts?

Replies are listed 'Best First'.
Re: Read file (cron)
by stajich (Chaplain) on Jul 04, 2002 at 01:49 UTC
    cron is run as the user that created the cronjob.

    But lots of things can go wrong here, not the least is the fact that you open a filehandle called TICKS but read the handle with <TICK>. But of course you say that the script actually runs when you test it out so that must not be it.

    So beyond that.

    • Test that you successfully opened the filehandle open(TICK,"textfile") or die("Cannot open file textfile"); or perhaps something more graceful.
    • Are you sure that the sequence of events which create the file have finished before your cron job starts?
    • What UID was the cronjob created as? If this is different than the UID which you are using to test the script then things won't be the same.
    • Do you use certain modules here that are included with your PERL5LIB or other methods - these ENV variables won't be set unless you add some code in your BEGIN block or play around with global environment variables for the shell.
    • Are you absolutely sure that your cronjob is running - have you debugged your script by having it open and print to a logfile?
      Sorry, that was a typo. It should be TICKS throughout. The sequence of events that generate the file are definetly finished before my cron job starts. How do I find out what UID the cron job was created versus what UID the script is run as?

      I'm positive that my cron job is running. I have it print out messages at different points in the program and i can view these in the /var/spool/mail files.
Re: Read file (cron)
by greenFox (Vicar) on Jul 04, 2002 at 02:36 UTC
    In my experience problems with running scripts from cron are invariably related to environment. Cron does not use the same shell or environment as a regular user. I would suggest implementing some error checking (this is a good idea any-way!) ie test for failure on your file open (as stajich has said) , use Strict and -w and in your cronjob redirect STDOUT and STDERR to a log so you can see what is happening ie.
    0 11 * * * /path/to/my/script.pl > /tmp/myscript.log 2>&1

    If you are still having problems you will have collected some more information to help locate it :)

    --
    my $chainsaw = 'Perl';

Re: Read file (cron)
by Abigail-II (Bishop) on Jul 04, 2002 at 10:11 UTC
    Well, it's not reporting any errors because you are not checking for any. As others have pointed out, things could go wrong with the open() call, but you are ignoring them. Why would Perl report anything if you silence it?

    As for cron, programs started by the cron daemon are run as the user who owns the crontab file - if all would be running as root, it would be really trivial to hack the system, wouldn't it? However, one should realize that the enviroment is different than running from the command line. There's no shell involved, so no profile is run setting up a myriad of environment variables. Furthermore, the working directory is likely to be different than when you run it from the command line. And since you are not using an absolute path, that's very likely the main cause of your problem.....

    Abigail

Re: Read file (cron)
by VSarkiss (Monsignor) on Jul 04, 2002 at 03:09 UTC

    No errors are reported,
    How could they be? You're not trying to find or report any. How about:
    open(TICKS,"textfile") or die "Can't open textfile: $!\n";
    Furthermore, your code is clobbering all but the last line, and printing that. Maybe you want:
    my $line_number = 0; while (<TICKS>) { # sic print "line $line_number: $_"; $line_number++; }
    At least that way you can tell if the file you're reading is the one you expected.

    Not trying to come down on you hard, but if you're "having trouble determining what is wrong", make the program tell you!

    HTH

Re: Read file (cron)
by amphiplex (Monk) on Jul 04, 2002 at 05:54 UTC
    Hi !

    You should propably use the full path to your textfile, and of course check the error, as the others already suggested:
    open TICKS, "/some/directory/textfile" or die "Couldn't open file: $!\ +n";
    ---- kurt