在cron下运行的程序会在错误的路径中创建文件

时间:2017-07-10 16:36:04

标签: perl cron

我正在尝试使用crontab执行Perl脚本。

手动,脚本运行正常,但是当我使用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        =>  'maha.mastouri@st.com',

            To          =>   'maha.mastouri@st.com', 

#       Cc      =>  'maha.mastouri@st.com',

            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(); 

3 个答案:

答案 0 :(得分:1)

cron context与登录shell非常不同。默认情况下它没有env vars。在我看来,您的程序依赖于$ENV{USER}来构建它的输出(或输入)。好吧,那个env var将会从cron中丢失。 crontabs由&#34; cron&#34;执行。守护进程,而不是您的登录shell。

您可以尝试将整个%ENV打印到&#34; /tmp/env.txt"只是为了看到它基本上是一个空哈希。如果您可以更改程序而不依赖于env var,那么它是最好的。您也可以尝试在计划行之前添加它们:

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

我还必须通知您,执行此操作后,env var USER将出现在这两行以下的所有计划中。 ps e也可以检查这些环境变量。

如果只需要env var来决定输入路径,那么就像从@ARGV获取输入路径一样简单

答案 1 :(得分:0)

它应该在执行cron.So中的命令之前运行你的.profile(or .bash_profile for bash,如图所示将它放在cron中的命令之前。同样,如果您在登录时运行的任何配置文件脚本都在perl脚本中使用,则必须包含这些脚本。

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

答案 2 :(得分:0)

我解决了这个问题,crontab在家里执行脚本&#34; / home / httpldev /&#34; (默认),所以我通过以下方式更改了执行路径;

0 9 1 * * cd / home / httpldev / iLicoMetrics /&amp;&amp; /home/httpldev/iLicoMetrics/metrique.pl& amp;&gt; / dev / null。

非常感谢你的帮助。

相关问题