【问题标题】:Die statement is not working in foreach loop in perlDie 语句在 perl 的 foreach 循环中不起作用
【发布时间】:2014-10-06 10:33:18
【问题描述】:

我的脚本从 FTP 下载文件并将文件移动到 FTP 中的存档目录。 我有一个在 FTP 中搜索文件的模式,并将其放入 foreach 循环中以将这些文件放入本地目录。

my $ftpUser     = 'xxxx';
my $ftpPW       = 'xxxxxx';
my $FTPHost     = "xxxxxxxxxxx";
my $remotefile  = 'CAP*.csv';
my $archivefile = "/usr/archive/CAP_${file_date_time}.csv";

my $ftp = Net::FTP->new($FTPHost);
$ftp->login( $ftpUser, $ftpPW ) or die print L1 "Could not login FTP :" . $ftp->message . "\n";
print L1 "Login to FTP was successfull\n";
$ftp->cwd("/")
    or die print L1 "ftp_cd failed: " . $ftp->message . "\n";
foreach my $file_to_fetch ( $ftp->ls($remotefile) ) {
    $ftp->get( $file_to_fetch, $localfile ) or die print L1 "Could not get file from FTP :" . $ftp->message . "\n";
    $remotefile = $file_to_fetch;
    print "\$file_to_fetch ::: $file_to_fetch\n";
    print L1 "File - ${file_to_fetch} Successfully Downloaded from FTP\n";
    $ftp->rename( $file_to_fetch, $archivefile )
        or die print L1 "Could not move file to archive directory :" . $ftp->message . "\n";
    print L1 "File - ${file_to_fetch} Moved to archive directory as CAP_${file_date_time}.csv\n";
}
$ftp->quit;

print L1 "FTP process was successfully completed\n";
if ( -s $localfile ) {
    open F1, "$localfile"
        or die( print L1 "$localfile cannot be opened for reading \n" );
} else {
    die( print L1 "$localfile does not exist \n" );
}

在执行上述代码时,如果我正在搜索的文件不在 FTP 中,但它没有打印“无法从 FTP 获取文件”日志的 die 语句,而是从 FTP 中出来并继续下一组代码打印 L1 "FTP 进程已成功完成\n"。

请帮助我解决这些问题,为什么 die 语句在 foreach 中不起作用,如果它无法从 FTP 获取文件。

【问题讨论】:

    标签: perl


    【解决方案1】:

    替换,

    $ftp->get($file_to_fetch,$localfile) or die print L1 "Could not get file from FTP :" . $ftp->message ."\n";
    

    $ftp->get($file_to_fetch,$localfile) or die "Could not get file from FTP :". $ftp->message ."\n";
    

    因为die 在第一种情况下将print() 返回值作为参数而不是错误消息。

    或者制作你自己的函数,

    sub mydie {
      my ($msg) = @_;
    
      print L1 $msg;
      die $msg;
    }
    

    或者如果函数不是一个选项,

    $ftp->get($file_to_fetch,$localfile) or do {
    
      print(L1 $_), die($_) for "Could not get file from FTP :". $ftp->message ."\n";
    };
    

    【讨论】:

    • 投下正确答案时请留下评论。
    • 这个答案没有解决为什么代码不会死,这是问题所在。
    • @darch OP 想要打印并以相同的消息终止,程序打印他想要的内容,但以1 消息终止。上面的答案解释了为什么没有所需的行为,以及如何完成它。所以代码肯定会死掉(eval.in/205481),但不是以 OP 想要的方式。
    【解决方案2】:

    您的问题出现是因为您将print 语句的返回值传递给die

    ... or die print L1 "Could not get file from FTP :" . $ftp->message . "\n";
    

    我怀疑您正在尝试将 die 语句的输出镜像到文件和 STDERR。

    如果是这种情况,那么我建议您执行以下操作:

    1. 将所有 die print L1 语句更改为仅 die

    2. 从每个 die 消息中删除尾随换行符 \n,因为这会隐藏行号信息。

      $ftp->login( $ftpUser, $ftpPW )
          or die "Could not login FTP :" . $ftp->message;
      
    3. 创建一个$SIG{__DIE__} 处理程序以将您的die 输出镜像到文件句柄。

      local $SIG{__DIE__} = sub {
          print L1 @_;
          die @_;
      };
      

    【讨论】:

    • 是的,半小时前。我考虑了对 OP 和可能的其他人的帮助信息,所以我会忽略它。
    猜你喜欢
    • 2018-11-19
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    相关资源
    最近更新 更多