2011-04-28 123 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