Linux 在命令行上运行但不在crontab中的perl脚本

Linux 在命令行上运行但不在crontab中的perl脚本,linux,perl,scripting,cron,rrdtool,Linux,Perl,Scripting,Cron,Rrdtool,很奇怪,我有很多脚本,比如follow,都在crontab中运行,但是follow脚本在命令行(./load.pl)上运行,而不是在crontab crontab: 0-59/5 * * * * /home/spatel/rrd/load.pl >> /tmp/load.out 注: 我也尝试了下面的方法 0-59/5 * * * * /usr/bin/perl /home/spatel/rrd/load.pl >> /tmp/load.out 0-59/5 * * *

很奇怪,我有很多脚本,比如follow,都在crontab中运行,但是follow脚本在命令行(./load.pl)上运行,而不是在
crontab

crontab:

0-59/5 * * * * /home/spatel/rrd/load.pl >> /tmp/load.out
注: 我也尝试了下面的方法

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
在某个地方,我读到了cron忽略新行结尾的脚本,所以我看起来也很在意

我已经在脚本中放入了
print
,并重定向到
/tmp/load.out
当cron执行时,我可以在
load.out
中看到输出,但不知何故它并没有更新side
load.rrd
文件中的数据

如果我像
/load.pl
那样在命令上运行脚本,它会工作!但不是在crontab内部

我已经设置了crontab
PATH
无论
root
使用什么。我尝试了所有可能的调试方法,但它并没有在cron内部运行。这里是我得到这个脚本的地方,crontab中的所有其他脚本工作文件只有一个有问题:(

脚本:

#!/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;
}

这很可能是环境问题

“cron”脚本以默认系统环境(默认路径、LANG等)开始。您的.profile、.rc不会执行

因此,您需要提供脚本中所需的所有环境变量路径等。对于纯perl脚本来说,这有点困难,因此最好将其包装在shell脚本中,以设置“.profile”脚本设置的内容。

您不会相信问题是如何解决的,我在
crontab
中使用
perl
而不是
/usr/bin/perl
,我认为在crontab中使用完整的
路径是最好的做法,但事实证明它是错误的,我仍然不知道原因和方法

0-59/5 * * * * perl /home/spatel/rrd/load.pl

当您在命令行中调用它而不在其实际目录中,并使用完整路径执行它时会发生什么情况?:)例如,cd~spatel/主/铲/rrd/装载。pl@tink我已经用脚本的
输出
更新了我的问题,如果在命令行上运行,它会生成带有数据的
RRD
图形,但是如果相同的脚本ii放入contab,那么它会创建
图形
,但是
没有
图形中的数据。在
contab
文件的顶部添加了完整的
路径
,我还尝试将
perl
脚本封装在
shell脚本中,但仍然无法执行它。有趣的是,所有其他perl脚本都运行良好。上面的脚本有一个问题,您可以在您的机器上试一试。最有可能的是:路径与
/usr/bin/perl
中发现不同的perl版本。perl前缀应该是不相关的-如果不指定它,操作系统将从您的脚本中读取shebang路径。@Sobrique:我已经尝试过shebang
#/usr/bin/perl
,但这也不起作用。我只有操作系统附带的标准perl安装。请尝试
哪个perl
:)@Sobrique获得相同的路径
哪个perl
输出
/usr/bin/perl
,即使该链接不是符号链接,因为cron不喜欢符号链接
0-59/5 * * * * perl /home/spatel/rrd/load.pl