简体   繁体   中英

Cronjob does not execute command line in perl script

I am unfamiliar with linux/linux environment so do pardon me if I make any mistakes, do comment to clarify.

I have created a simple perl script. This script creates a sql file and as shown, it would execute the lines in the file to be inserted into the database.

#!/usr/bin/perl

use strict;
use warnings;
use POSIX 'strftime';

my $SQL_COMMAND;
my $HOST = "i";
my $USERNAME = "need";
my $PASSWORD = "help";
my $NOW_TIMESTAMP = strftime '%Y-%m-%d_%H-%M-%S', localtime;

open my $out_fh, '>>', "$NOW_TIMESTAMP.sql" or die 'Unable to create sql file';

printf {$out_fh} "INSERT INTO BOL_LOCK.test(name) VALUES ('wow');";

sub insert()
{
    my $SQL_COMMAND = "mysql -u $USERNAME -p'$PASSWORD' ";

    while( my $sql_file = glob '*.sql' )
    {
        my $status = system ( "$SQL_COMMAND < $sql_file" );
        if ( $status == 0 )
        {
           print "pass";
        }
        else
        {
           print "fail";
        }
    }
}

insert();

This works if I execute it while I am logged in as a user(I do not have access to Admin). However, when I set a cronjob to run this file let's say at 10.08am by using the line(in crontab -e ):

08 10 * * * perl /opt/lampp/htdocs/otpms/Data_Tsunami/scripts/test.pl > /dev/null 2>&1

I know the script is being executed as the sql file is created. However no new rows are inserted into the database after 10.08am. I've searched for solutions and some have suggested using the DBI module but it's not available on the server.

EDIT: Didn't manage to solve it in the end. A root/admin account was used to to execute the script so that "solved" the problem.

First things first, get rid of the > /dev/null 2>&1 at the end of your crontab entry (at least temporarily) so you can actually see any errors that may be occurring.

In other words, change it temporarily to something like:

08 10 * * * perl /opt/lampp/htdocs/otpms/Data_Tsunami/scripts/test.pl >/tmp/myfile 2>&1

Then you can examine the /tmp/myfile file to see what's being output.

The most likely case is that mysql is not actually on the path in your cron job, because cron itself gives a rather minimal environment.

To fix that problem (assuming that's what it is), see this answer , which gives some guidelines on how best to expand the cron environment to give you what you need. That will probably just involve adding the MySQL executable directory to your PATH variable.

The other thing you may want to consider is closing the out_fh file before trying to pass it to mysql - if the buffers haven't been flushed, it may still be an empty file as far as other processes are concerned.

The expression glob(".* *") matches all files in the current working directory. - http://perldoc.perl.org/functions/glob.html

you should not rely on the wd in a cron job. If you want to use a glob (or any file operation) with a relative path, set the wd with chdir first. source: http://www.perlmonks.org/bare/?node_id=395387

So if your working directory is, for example /home/user , you should insert

chdir('/home/user/');

before the WHILE , ie:

sub insert()
{
    my $SQL_COMMAND = "mysql -u $USERNAME -p'$PASSWORD' ";

    chdir('/home/user/');

    while( my $sql_file = glob '*.sql' )
    {
...

replace /home/user with wherever your sql files are being created.

It's better to do as much processing within Perl as possible. It avoids the overhead of generating a separate shell process and leaves everything under the control of the program so that you can handle any errors much more simply

Database access from Perl is done using the DBI module . This program demonstrates how to achieve what you have written using the mysql utility. As you can see it's also much more concise

#!/usr/bin/perl

use strict;
use warnings;

use DBI;

my $host     = "i";
my $username = "need";
my $password = "help";

my $dbh = DBI->connect("DBI:mysql:database=test;host=$host", $username, $password);

my $insert = $dbh->prepare('INSERT INTO BOL_LOCK.test(name) VALUES (?)');

my $rv = $insert->execute('wow');

print $rv ? "pass\n" : "fail\n";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM