It is very strange, i have many script like following and all running in crontab but following script running on command (./load.pl) line but not inside crontab
crontab:
0-59/5 * * * * /home/spatel/rrd/load.pl >> /tmp/load.out
Notes: I also tried following method
0-59/5 * * * * /usr/bin/perl /home/spatel/rrd/load.pl >> /tmp/load.out
0-59/5 * * * * root /usr/bin/perl /home/spatel/rrd/load.pl >> /tmp/load.out
Somewhere i read cron ignore newline end of the script so i look care of that too
I have put print
in script and redirect to /tmp/load.out
i can see that output in load.out
when cron execute but somehow it is not updating data in side load.rrd
file.
If i run script on command like ./load.pl
it works! but not inside crontab.
I have set crontab PATH
whatever root
use has. I tried all possible way to debug but it is not running inside cron. Here is the place where i get this script, all other script working file in crontab only following one has issue :( https://github.com/mmitch/rrd
Script:
#!/usr/bin/env perl
#
# RRD script to display system load
# 2003,2011 (c) by Christian Garbs <mitch@cgarbs.de>
# Licensed under GNU GPL.
#
# This script should be run every 5 minutes.
#
# *ADDITIONALLY* data aquisition is done externally every minute:
# rrdtool update $datafile N:$( PROCS=`echo /proc/[0-9]*|wc -w|tr -d ' '`; read L1 L2 L3 DUMMY < /proc/loadavg ; echo ${L1}:${L2}:${L3}:${PROCS} )
#
use strict;
use warnings;
#use 5.010;
use RRDs;
# parse configuration file
my %conf;
eval(`/bin/cat /home/spatel/rrd/rrd-conf.pl`);
die $@ if $@;
# set variables
my $datafile = "/home/spatel/rrd/db/load.rrd";
my $picbase = "/var/www/mrtg/rrd/load-";
# global error variable
my $ERR;
# whoami?
my $hostname = `/bin/hostname`;
chomp $hostname;
# generate database if absent
if ( ! -e $datafile ) {
# max 70000 for all values
RRDs::create($datafile,
"--step=60",
"DS:load1:GAUGE:120:0:70000",
"DS:load2:GAUGE:120:0:70000",
"DS:load3:GAUGE:120:0:70000",
"DS:procs:GAUGE:120:0:70000",
"RRA:AVERAGE:0.5:1:120",
"RRA:AVERAGE:0.5:5:600",
"RRA:AVERAGE:0.5:30:700",
"RRA:AVERAGE:0.5:120:775",
"RRA:AVERAGE:0.5:1440:797",
"RRA:MAX:0.5:1:120",
"RRA:MAX:0.5:5:600",
"RRA:MAX:0.5:6:700",
"RRA:MAX:0.5:120:775",
"RRA:MAX:0.5:1440:797",
"RRA:MIN:0.5:1:120",
"RRA:MIN:0.5:5:600",
"RRA:MIN:0.5:6:700",
"RRA:MIN:0.5:120:775",
"RRA:MIN:0.5:1440:797"
);
$ERR=RRDs::error;
die "ERROR while creating $datafile: $ERR\n" if $ERR;
print "created $datafile\n";
}
# data aquisition is done externally every minute:
my @procs = glob '/proc/[0-9]*';
my $file = '/proc/loadavg';
open my $fh, '<', $file or die "Failed to open '$file': $!";
my $load = <$fh>;
my $p = (scalar @procs);
my $l = (join ':', (split ' ', $load)[0..2]);
print "${l}:${p}";
# update rrd
RRDs::update($datafile,
"N:${l}:${p}"
);
$ERR=RRDs::error;
die "ERROR while updating $datafile: $ERR\n" if $ERR;
# draw pictures
foreach ( [3600, "hour"], [86400, "day"], [604800, "week"], [31536000, "year"] ) {
my ($time, $scale) = @{$_};
RRDs::graph($picbase . $scale . ".png",
"--start=-${time}",
'--lazy',
'--imgformat=PNG',
"--title=${hostname} system load (last $scale)",
"--width=$conf{GRAPH_WIDTH}",
"--height=$conf{GRAPH_HEIGHT}",
'--slope-mode',
'--alt-autoscale',
"DEF:load1=${datafile}:load1:AVERAGE",
"DEF:load2=${datafile}:load2:AVERAGE",
"DEF:load3=${datafile}:load3:AVERAGE",
"DEF:procsx=${datafile}:procs:AVERAGE",
"DEF:procminx=${datafile}:procs:MIN",
"DEF:procmaxx=${datafile}:procs:MAX",
'CDEF:procs=procsx,100,/',
'CDEF:procmin=procminx,100,/',
'CDEF:procrange=procmaxx,procminx,-,100,/',
'AREA:procmin',
'STACK:procrange#E0E0E0',
'AREA:load3#000099:loadavg3',
'LINE2:load2#0000FF:loadavg2',
'LINE1:load1#9999FF:loadavg1',
'COMMENT:\n',
'LINE1:procs#000000:processes/100',
);
$ERR=RRDs::error;
die "ERROR while drawing $datafile $time: $ERR\n" if $ERR;
}
Here is the output of script:
[root@spatel tmp]# pwd
/tmp
[root@spatel tmp]# /home/spatel/rrd/load.pl
0.15:0.06:0.01:664
Its most likely an environment problem.
A "cron" scripts starts of with the default system environment (Default PATH, LANG etc.) your .profile, .rc are NOT executed.
So you need to provide all the environment variables PATHs etc. your program requires in the script. This is a bit of a pain for a pure perl script so its probably better to wrap it in a shell script which sets whatever your ".profile" script sets.
You won't believe how problem got resolved, I use perl
instead of /usr/bin/perl
in crontab
, I though its best practice to use full PATH
in crontab but it prove wrong, Still i don't know why and How?
0-59/5 * * * * perl /home/spatel/rrd/load.pl
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.