2017-07-10 6 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

"not readable"というメッセージは、perlインタプリタやシステムによって生成されたものではありません( 'man errno'や' perldoc perldiag'ではなく)。私はそれがあなたのプログラムの文字列であると推測しています。どうやらあなたはすでにファイルの可用性をチェックしているのです。私はあなたがシステムコールを扱っているときには、いつもあなたのメッセージ出力に '$!'を含めておくことをお勧めします - 通常は理由を示します。 – gugod

答えて

1

のcronコンテキストは、ログインシェルよりも非常に異なっています。デフォルトではenv変数はありません。あなたのプログラムは出力(または入力)を構築するために$ENV{USER}に依存しているようです。まあ、そのenv varはちょうどcronから行方不明になるだろう。 crontabは、あなたのログインシェルではなく "cron"デーモンによって実行されます。

%ENV全体を "/tmp/env.txt"のような場所に印刷すると、基本的に空のハッシュであることがわかります。 env varに依存しないようにプログラムを変更することができれば最高です。また、右側の日程行の前に戻ってそれらを追加しようとする場合があります。

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

私もこれを実行した後、ENVするvarユーザーはこれらの2行以下のすべてのスケジュールの存在になっていることを通知しなければなりません。これらの環境はps eで検査することもできます。

のenv varがちょうどそれはそれは実行する必要があります@ARGV

+0

'cron 'で'&> 'を移植することはできません。正しい移植可能な表現は '/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 cron.Soからコマンドを実行する前に)bashのために、置きますそれはあなたのコマンドの前にcronで示されています。同様に、ログイン時にperlスクリプトで使用されるプロファイルスクリプトがあれば、それらをインクルードする必要があります。

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

は、私が「/ホーム/ httpldev /」(デフォルト)のcrontabが自宅でスクリプトを実行し、問題を解決したので、私は次によって実行パスを変更しました。

0 9 1 * * CD /ホーム/ httpldev/iLicoMetrics/& & /home/httpldev/iLicoMetrics/metrique.pl &>を/ dev/null。

ありがとうございました。

関連する問題