2015-08-19 88 views
0

我不熟悉linux/linux環境,所以如果我犯了任何錯誤,請原諒我,做一下評論澄清。Cronjob在perl腳本中不執行命令行

我創建了一個簡單的perl腳本。該腳本創建一個sql文件,如圖所示,它將執行要插入數據庫的文件中的行。

#!/usr/bin/perl 

use strict; 
use warnings; 
use POSIX 'strftime'; 

my $SQL_COMMAND; 
my $HOST = "i"; 
my $USERNAME = "need"; 
my $PASSWORD = "help"; 
my $NOW_TIMESTAMP = strftime '%Y-%m-%d_%H-%M-%S', localtime; 

open my $out_fh, '>>', "$NOW_TIMESTAMP.sql" or die 'Unable to create sql file'; 

printf {$out_fh} "INSERT INTO BOL_LOCK.test(name) VALUES ('wow');"; 

sub insert() 
{ 
    my $SQL_COMMAND = "mysql -u $USERNAME -p'$PASSWORD' "; 

    while(my $sql_file = glob '*.sql') 
    { 
     my $status = system ("$SQL_COMMAND < $sql_file"); 
     if ($status == 0) 
     { 
      print "pass"; 
     } 
     else 
     { 
      print "fail"; 
     } 
    } 
} 

insert(); 

這工作,如果我作爲用戶登錄時(我沒有訪問管理員)執行它。但是,當我設置一個cronjob運行此文件,讓我們在上午10時08說,通過使用行(crontab -e):

08 10 * * * perl /opt/lampp/htdocs/otpms/Data_Tsunami/scripts/test.pl > /dev/null 2>&1 

我知道作爲創建SQL文件正在執行的腳本。但是,上午10點08分之後沒有新行插入到數據庫中。我已經搜索瞭解決方案,有些人建議使用DBI模塊,但它在服務器上不可用。

編輯:沒有設法解決它到底。使用root/admin帳戶來執行腳本,以便「解決」問題。第一

+2

你是否有理由避免['DBI'模塊](http://metacpan.org/module/DBI)? – Borodin

+0

你可以把'printf'改成'print'嗎? [docs](http://perldoc.perl.org/functions/printf.html)有一些有趣的說法,就是在文件句柄中使用'printf'並且沒有列表。 –

+0

@MattJacob:只使用格式字符串而不使用'printf'沒有問題。文檔中關於省略的「列表」包含格式,如'printf FH',它等同於'printf FH $ _',但是具有像'printf $ fh'這樣的詞法文件句柄。Perl將解釋爲打印到當前 - 選擇的輸出句柄使用字符串化文件句柄'「$ fh」'作爲格式字符串 – Borodin

回答

2

第一件事,擺脫了> /dev/null 2>&1在您crontab項的末尾(至少暫時),所以實際上你可以看到可能發生的任何錯誤。

換句話說,暫時將其更改爲類似:

08 10 * * * perl /opt/lampp/htdocs/otpms/Data_Tsunami/scripts/test.pl >/tmp/myfile 2>&1 

然後你可以檢查/tmp/myfile文件,看看有什麼是輸出。

可能情況是mysql實際上不是在你的cron工作的道路上,因爲cron本身給出了一個相當最小的環境。

要解決這個問題(假設它就是這樣),請參閱this answer,它提供了一些關於如何最好地擴展環境以提供所需內容的指導。這可能只涉及將MySQL可執行文件目錄添加到您的變量PATH

您可能要考慮的另一件事是在嘗試將它傳遞給mysql之前關閉out_fh文件 - 如果緩衝區沒有被刷新,就其他進程而言,它仍可能是空文件。

+0

它說'sh:mysql:命令沒有找到 失敗'幾次然後有'SQL文件大小爲0'。後者是我添加的一個檢查,用於檢查文件大小是否爲0.不知道爲什麼'找不到'命令。它在我手動執行文件時運行並插入,但不是在通過cronjob執行時插入。對不起,晚了(誰也在讀書)。 – hzq

+0

@hzq,那麼它確實是我的想法。 MySQL不在你的cronjob的路徑上,因爲'cron'給你一個相當小的環境。有關如何解決,請參閱http://stackoverflow.com/questions/1972690/cannot-get-php-cron-script-to-run/1972763#1972763,http://stackoverflow.com/questions/3295611/how-可以,我的故障排除,爲什麼,我的PHP腳本,不會工作在克朗,當它從/ TH/3295657#3295657或http://stackoverflow.com/questions/1068071/include-路徑和-的cron/1068084#1068084。 – paxdiablo

0

表達式glob(「。* *」)匹配當前工作的 目錄中的所有文件。 - http://perldoc.perl.org/functions/glob.html

你不應該依賴於cron作業中的wd。如果你想用相對路徑使用glob(或任何文件操作),首先用chdir設置wd。 來源:http://www.perlmonks.org/bare/?node_id=395387

所以,如果你的工作目錄,例如/home/user,你應該插入

chdir('/home/user/'); 

WHILE之前,即:

sub insert() 
{ 
    my $SQL_COMMAND = "mysql -u $USERNAME -p'$PASSWORD' "; 

    chdir('/home/user/'); 

    while(my $sql_file = glob '*.sql') 
    { 
... 

與地方的SQL文件替換/home/user被創建。

+0

更好:不要使用glob,併爲所有文件和目錄構建完整路徑。 –

+0

這樣做會更好,但我的嘗試是直接回答這個人的問題,「爲什麼這不起作用?」而不是全部說教。 –

+0

是的,我只是想明白爲什麼。我按照你的建議嘗試過,但我遇到了同樣的問題。 – hzq

0

最好在Perl中儘可能多地進行處理。它避免了生成一個單獨的shell進程的開銷,並將所有內容留在程序的控制之下,以便您可以更簡單地處理任何錯誤。

Perl的數據庫訪問使用DBI module完成。該程序演示如何實現您使用mysql實用程序編寫的內容。正如你可以看到它也更加簡潔

#!/usr/bin/perl 

use strict; 
use warnings; 

use DBI; 

my $host  = "i"; 
my $username = "need"; 
my $password = "help"; 

my $dbh = DBI->connect("DBI:mysql:database=test;host=$host", $username, $password); 

my $insert = $dbh->prepare('INSERT INTO BOL_LOCK.test(name) VALUES (?)'); 

my $rv = $insert->execute('wow'); 

print $rv ? "pass\n" : "fail\n"; 
+1

原來的帖子說DBI沒有安裝在服務器上。 –