2011-04-28 143 views
1

我是新來的perl,並試圖使用LFTP程序創建一個FTP腳本。Perl外部命令執行錯誤

我試圖通過LFTP執行一個FTP腳本文件。我的代碼是:

my $CLIENT = "lftp"; 
my $connectionString = "" . $CLIENT . " -d -f script.ftp"; 
my $result = `$connectionString` or die "\nERROR running $CLIENT: $!"; 
return $result; 

嗯,這是完全從script.ftp文件執行所有的命令調試是查看輸出,之後只是送死而已寫入$result。我收到

錯誤是 -

ERROR running lftp: at ftp.pl line 3. 

它指的是我的輸出傳遞到變量$result線。

任何線索爲什麼它沒有通過輸出到$result,只是死?

如果我從Linux外殼運行相同,它完美執行沒有錯誤。

+0

[可能的重複(http://perlmonks.org/?node_id=901863)。 :) – tchrist 2011-04-28 22:51:36

回答

2

更好地使用FTP模塊(例如Net::FTP),而不是依靠shell/external命令。

+0

使用LFTP的原因是針對FTPSSL和SFTP。 – 2011-04-28 20:35:38

+0

那麼Net :: SFTP或Net :: FTPSSL怎麼樣? – snoofkin 2011-04-28 20:37:04

+0

我知道我可以使用它們。但是,想法是將這個客戶端用於所有FTP連接類型的單一功能,只是傳遞加密方法和端口,而不是針對不同的加密類型編寫不同的功能。 – 2011-04-28 20:43:16

0

這不是一個真正的錯誤,你只是將它定義爲錯誤。系統調用的返回值被perl解釋爲false,從而觸發die子句。

+0

這不是系統調用,它是對系統的調用。 :)無論如何,false是空字符串或零。不知道它是什麼? :) – tchrist 2011-04-28 21:04:33

+0

空字符串,零或undef,而是。我猜不到,但如果我是他,我會檢查返回值。 – TLP 2011-04-28 21:19:16

+0

不,undef是空字符串或零。已經涵蓋。 – tchrist 2011-04-28 22:35:37

2

命令是否將任何內容寫入標準輸出(與標準錯誤相反)?反引號的返回值是程序的實際輸出。如果輸出爲空,則$result的值爲「false」,並調用die語句。

一些替代方案:

使用system因爲system返回值告訴你的命令是否成功與否:

system($connectionString) and die "ERROR: running $CLIENT: $?\n" 

system("$connectionString > $logFile 2>&1") 
    and die "ERROR in $CLIENT: $?. Look in $logFile\n"; 

(我們使用and,而不是or因爲不像其他大多數職能的工作,從system返回值爲零表示成功)。

另一種選擇是加入外部命令的標準輸出和標準誤差,從而該命令成功時的唯一輸出是「錯誤」的輸出,諸如調試消息:

$result = `$connectionString 2>&1` or die "ERROR: running CLIENT: $!\n"; 


(編輯受歡迎的需求)另一種選擇是條件$?(最後一次外部命令運行的退出狀態):

$result = `$connectionString`; 
$? == 0 or die "ERROR: running CLIENT: $! $?\n"; 
+0

非常感謝。那麼,如果我運行system()函數,它完美運行,沒有任何錯誤消息。但是,我需要保存輸出日誌以生成報告。任何想法 ? – 2011-04-28 20:52:27

+3

使用反引號運行它,就像您最初存儲命令的輸出一樣,但之後檢查表示失敗或成功的實際返回代碼的'$?'特殊變量。 – cikkle 2011-04-28 20:58:36

+0

返回碼$?是 – 2011-04-29 13:00:30

1

執行系統命令並檢查錯誤將如下所述的適當的方式:

 
my $result = `$connectionString`; 
my $rc = $? >> 8; 
if($rc){ 
    die("Error executing command: $!\n"); 
}else{ 
    print "Success!\n"; 
} 
return $result; 
+1

這是Perl,所以正確的說法是「正確的方法......」 – 2011-04-29 05:16:53

+0

如果我檢查錯誤,它會返回成功。但是,沒有任何信息傳遞給$ result。任何想法 ?? – 2011-04-29 12:54:19

+0

你的命令是否實際產生任何輸出到STDOUT?如果在命令行中使用'2>/dev/null'結束命令,會發生什麼?如果在命令行中沒有輸出,perl程序也不會在$ result中得到任何結果。 – bot403 2011-05-02 17:29:12