2017-07-10 43 views
-1

我正在尝试使用crontab执行Perl脚本。在cron下运行的程序创建错误路径文件

手动,脚本工作正常,但是当我用cron,我得到一个错误

/home/dev/test.csv:无法读取

/home/dev/test.csv由生成的文件该脚本,但它创建为/home/test.csv和 我不知道如何或为什么。

这是我的crontab:

/3 * * * * /home/dev/metrique.pl &> /home/dev/output.txt 

这是我的代码:

#!/sw/freetools/perl/5.8.8/Linux/rh50/x86_64/bin/perl 

#use strict ; 
#use warnings ; 
use DBI ; 
use DateTime ; 
use Text::CSV; 
use MIME::Lite; 

my $Month = DateTime->now->subtract(months=>0)->truncate(to=>'month') ->strftime('%B') ; 
my $Date = DateTime->now->subtract(months=>0)->truncate(to=>'month') ->strftime('%Y-%m') ; 
$Date ="%".$Date."%" ; 
my %info = (db => "ilico", host => "gnx5910.gnb.st.com", user => "ilicousr", pass => ""); 
my $dbh = DBI->connect("DBI:mysql:$info{db};$info{host}", $info{user}, $info{pass}); 
my @record ;   
my %Report; 
my @other; 
my @region = qw{EMEA AME ASIA INDIA Global-WAN}; 
my @scope = qw{wan lan specific}; 
my $total_weekly = 0; 
my $total_usage = 0; 
my $weekly = '2'; 
my $usage = '1'; 
my @top_user ; 
my @array ; 
my @user ; 
my %hash =(); 
my %sum =(); 
my %LOGIN_W =(); 
my %Groupe =(); 
my %hash1 =(); 
my %Nom_Complet =(); 
my %NUMBER =(); 

my $filename1="NBgenerated_Reports.csv"; 
my $filename2="Report_Scope.csv"; 
my $filename3 ="Top_10_Features.csv"; 
my $filename4 ="Top_10_Users.csv"; 
my $filename5 ="/sw/st/itcad/setup/shared_data/ldp_om.csv"; 
my $filename6 ="Report_Groupe.csv"; 

open(my $fh1, ">", $filename1) or die "cannot open < $filename1: $!"; 
open(my $fh2, ">", $filename2) or die "cannot open < $filename2: $!"; 
open(my $fh3, ">", $filename3) or die "cannot open < $filename3: $!"; 
open(my $fh4, ">", $filename4) or die "cannot open < $filename4: $!"; 
open(my $fh5, "<", $filename5) or die "cannot open < $filename5: $!"; 
open(my $fh6, ">", $filename6) or die "cannot open < $filename6: $!"; 

print $fh1 "Region; Usage_Report; Weekly; \n"; 
print $fh2 "Scope; NB; \n"; 
print $fh3 "Feature; NB; \n"; 
print $fh4 "User; NB_Report ;Groupe \n"; 
print $fh6 "Groupe; NB_Report \n"; 


#usage & weekly 
my $sql = qq/SELECT COUNT(`Region`.`RegID`) FROM `iLico_Log`, `Region` WHERE `iLico_Log`.`Date` LIKE ? AND `Region`.`RegID` = `iLico_Log`.`RegID` AND `iLico_Log`.`Type` = ? 
     AND `Region`.`RegName` LIKE ?/; 

foreach my $reg (@region){ 
foreach my $type ($weekly, $usage){ 
    my $sth = $dbh->prepare($sql) or die ("unable to prepare"); 
    $sth->execute(($Date, $type, $reg)) ; 
    @record = $sth -> fetchrow_array(); 
     $Report{$reg}{$type}=$record[0]; 
    } 
} 

foreach my $reg (keys %Report) { 
    $total_usage += $_ for($Report{$reg}{$usage}); 
    $total_weekly += $_ for($Report{$reg}{$weekly}); 
    print $fh1 "$reg ; $Report{$reg}{$usage}; $Report{$reg}{$weekly} \n"; 
    } 

    print $fh1 "total; $total_usage; $total_weekly; \n"; 

#scope 
my $SCOPE = qq/SELECT COUNT(logID) FROM `iLico_Log` WHERE `iLico_Log`.`Date` LIKE ? AND `iLico_Log`.`scope`= ?/; 
foreach my $sc (@scope){ 
    my $sth = $dbh->prepare($SCOPE) or die ("unable to prepare"); 
     $sth->execute($Date, $sc) ; 
     my @record = $sth -> fetchrow_array(); 
    print $fh2 "$sc; @record; \n"; 
    } 

#Top 10 features 
my $TopFeatures = qq/SELECT `Feature`.`FeatName` , COUNT(*) NB FROM `iLico_Log`, `Feature` WHERE `iLico_Log`.`Date` LIKE ? AND `iLico_Log`.`FeatID` = `Feature`.`FeatID` GROUP BY `Feature`.`FeatID` ORDER BY NB DESC LIMIT 10 /; 

my $sth = $dbh->prepare($TopFeatures) or die ("unable to prepare"); 
    $sth->execute($Date) ; 
    while(@record = $sth -> fetchrow_array()) 
     { 
    print $fh3 "$record[0]; $record[1]; \n"; 
     } 

#other features number 
my $Other = qq/SELECT COUNT(DISTINCT `iLico_Log`.`FeatID`) NB FROM `iLico_Log`, `Feature` WHERE `iLico_Log`.`Date` LIKE ? AND `iLico_Log`.`FeatID` = `Feature`.`FeatID`/; 
$sth = $dbh->prepare($Other) or die ("unable to prepare"); 
     $sth->execute($Date) ; 
     @record = $sth -> fetchrow_array(); 
    $other[0] = $record[0] - 10 ; 
     print $fh3 "Other_features_number; @other \n"; 

#total usage of all and other features 
my $TotalUsage =qq/SELECT COUNT(*) SU FROM `iLico_Log` , `Feature` WHERE `iLico_Log`.`Date` LIKE ? AND `iLico_Log`.`FeatID` = `Feature`.`FeatID`/; 
my $SUMTopFeatures = qq/select sum(NB) from (SELECT `Feature`.`FeatName` , COUNT(*) NB FROM `iLico_Log`, `Feature` WHERE `iLico_Log`.`Date` LIKE ? AND `iLico_Log`.`FeatID` = `Feature`.`FeatID` GROUP BY `Feature`.`FeatID` ORDER BY NB DESC LIMIT 10) AS subquery /; 

$sth = $dbh->prepare($TotalUsage) or die ("unable to prepare"); 
my $sth1 = $dbh->prepare($SUMTopFeatures) or die ("unable to prepare"); 
    $sth->execute($Date) ; 
    $sth1->execute($Date) ; 
    @record = $sth -> fetchrow_array(); 
    my @sum = $sth1 -> fetchrow_array(); 
    $other[0] = $record[0] - $sum[0] ; 
     print $fh3 "Other_total_usage; @other"; 


#select login windows and groupe from file ldp_om.csv to be used in top_10_user and nomber Report/Groupe 
while (<$fh5>) { 
    chomp; 
     my ($mail, $uid, $site, $grp, $dvs, $cnt, $ccost, $mng, $typ, $phone, $first, $last, $login, $cn) = split ';', lc($_), 14; 
    if (! exists $LOGIN_W{$login}) { 
      $LOGIN_W{$login} = $grp; 
     } 

     if (! exists $hash{$login}) { 
      $Groupe{$login} = $grp; 
     $Nom_Complet{$login} = $cn; 
    } 
} 

#top 10 user/Groups 
my $TopUsers = qq/select ilicoUserLogin, COUNT(*) NB, Display from ilico_log I where Date like ? GROUP BY I.ilicoUserLogin ORDER BY NB DESC LIMIT 10/; 
$sth = $dbh->prepare($TopUsers) or die ("unable to prepare"); 
$sth->execute($Date) ; 
    while(@top_user = $sth -> fetchrow_array()) 
     { 
    $top_user[0] =~ s/\s+/ /g; 
     push (@array, lc($top_user[0])); 
    my $login = lc($top_user[0]); 
    $NUMBER{$login} = $top_user[1]; 
     } 

foreach my $login (@array){ 
    $hash1{$login} = $Groupe{$login}; 
} 

foreach my $login (sort {$NUMBER{$b} <=> $NUMBER{$a}} keys %hash1) { 
    my $grpe = uc($hash1{$login}) ; 
    my $name = ucfirst($Nom_Complet{$login}); 
    print $fh4 "$name ; $NUMBER{$login} ; $grpe ; \n"; 
} 

#Report/Groupe 
my $Groupe = qq/select ilicoUserLogin, Count(*) NB from ilico_log I where Date like ? GROUP BY I.ilicoUserLogin ORDER BY NB DESC /; 
$sth = $dbh->prepare($Groupe) or die ("unable to prepare"); 
$sth->execute($Date) ; 
while(@user = $sth -> fetchrow_array()) 
     { 
    $user[0] =~ s/\s+/ /g; 
     my $login = lc($user[0]); 
    $LOGIN_W{my $grp}{$login} = $user[1]; 
     } 

foreach my $login (keys %LOGIN_W) { 
    if (defined($login) and $login ne '') 
    { 
     $sum{$LOGIN_W{$login}} += $LOGIN_W{my $var}{$login} ; 
    } 
} 

for my $key (sort {$sum{$b} <=> $sum{$a}} keys %sum) { 
    if ($sum{$key}) 
    { 
     my $KEYS = uc($key); 
     print $fh6 "$KEYS; $sum{$key}; \n"; 
    } 
} 

close $fh1; 
close $fh2; 
close $fh3; 
close $fh4; 
close $fh5; 
close $fh6; 

my $msg = MIME::Lite->new ( 

      From  => '[email protected]', 

      To   => '[email protected]', 

#  Cc  => '[email protected]', 

      Subject  => "iLico Mertique $Month", 

     Type  => 'text/plain' , 

      Path => '/home/dev/text' 

); 



$msg->attach( Type  => 'TEXT', 

       Path  => '/home/dev/NBgenerated_Reports.csv', 

       Disposition => 'attachment', 
     Filename => 'NB_generated_Reports.csv' 

); 

$msg->attach( Type  => 'TEXT', 

       Path  => '/home/dev/Top_10_Features.csv', 

       Disposition => 'attachment', 
     Filename => 'Top_10_Features.csv' 

); 


$msg->attach( Type  => 'TEXT', 

       Path  => '/home/dev/Report_Scope.csv', 

       Disposition => 'attachment', 
     Filename => 'Report_Scope.csv' 

); 

$msg->attach( Type  => 'TEXT', 

       Path  => '/home/dev/Top_10_Users.csv', 

       Disposition => 'attachment', 
     Filename => 'Top_10_Users.csv' 

); 


$msg->attach( Type  => 'TEXT', 

       Path  => '/home/dev/Report_Groupe.csv', 

       Disposition => 'attachment', 
     Filename => 'Report_Groupe.csv' 

); 

$msg->send(); 
+0

什么是失败?显示代码。 /// 是什么原因?当'open'失败时,它将错误原因放在'$!'中。 – ikegami

+0

你可能会打开一个相对路径的文件,'cron'可能会做一个'chdir'。请显示你的代码。 – zdim

+0

“不可读”的消息看起来不像perl解释器或系统产生的东西(不在'man errno'中,也不在'perldoc perldiag'中)。我猜这是你程序中的一个字符串。显然你的程序正在检查文件的可用性。我建议,当你处理系统调用时,总是在你的消息输出中包含'$!' - 这通常说明了一个原因。 – gugod

回答

1

cron的上下文是不是一个登录shell非常不同。它默认没有环境变量。在我看来,你的程序依赖于$ENV{USER}来构建它的输出(或输入)。那么,env var只会从cron中丢失。 crontabs是由“cron”守护进程执行的,而不是你的登录shell。

您可以尝试将整个%ENV打印到“/tmp/env.txt”之类的地方,以查看它基本上是空的散列。这是最好的,如果你可以改变程序不依赖于env var。你也可以尝试在计划行权之前,将它们添加回:

USER=dev 
/3 * * * * /home/dev/metrique.pl &> /home/dev/output.txt 

我还要通知你,这样做之后,的环境变量用户将成为本作以下这两条线的所有计划。那些环境变化也可以通过ps e进行检查。

如果的环境变量只是决定输入路径,比它从@ARGV

+0

你不能在''cron'中使用'&gt'。正确的,可移植的表达式是'/home/dev/metrique.pl> /home/dev/output.txt 2&1' – tripleee

+0

@tripleee,我用/home/dev/metrique.pl>/home/dev/output .txt 2>&1。但仍然是同样的错误。 – maha

+0

是的,我不认为这是唯一的问题,你的问题太粗暴了。尝试制作[mcve]。 – tripleee

0

获取输入路径一样简单它应该运行需要你的.profile(or .bash_profile对于bash)从cron.So执行命令之前,把它在你的命令在cron之前如图所示。同样,如果在perl脚本中使用登录时运行的任何配置文件脚本,则必须包含这些脚本。

/3 * * * * . $HOME/.profile; /home/dev/metrique.pl &> /home/dev/output.txt 
0

我解决了这个问题,crontab中在家里执行脚本 “的/ home/httpldev /”(默认值),所以我按照改变的执行路径;

0 9 1 * * CD /家庭/ httpldev/iLicoMetrics/& & /home/httpldev/iLicoMetrics/metrique.pl &>的/ dev/null的。

非常感谢您的帮助。