追加文件间歇性失败

时间:2018-07-23 06:01:32

标签: perl

我正在使用下面的脚本添加两个文件,但它间歇性地添加失败,没有错误输出。

(my $file1, my $file2) = @ARGV;

open(FILE1, ">>$file1");
open(FILE2, "<$file2");

while ( <FILE2> ) {
    print FILE1 $_;
}

close(FILE2);
close(FILE1); 

上面的代码有问题吗?

2 个答案:

答案 0 :(得分:7)

您的代码的主要问题是它包含许多可能会失败的操作,但您没有检查错误,因此,如果失败,程序将以静默方式继续进行操作。

代码中可能会失败的三个函数是openprintclose。在每种情况下,该函数都会在成功或失败时返回一个真值,将返回一个假值,还将失败消息存储在特殊的全局变量$!中。

您写了:

open(FILE1,">>$file1");

最好写成:

open(my $out, '>>', $file1) || die "open(>>$file1): $!";

或者您可以使用较低优先级的or运算符并跳过括号:

open my $out, '>>', $file1 or die "open(>>$file1): $!";

您可以简单地调用die $!,但这会给您类似Permission denied的错误消息,并且不会告诉您哪个操作失败了(尽管die会在失败的位置添加行号发生)。有时,失败是由于以下事实:包含文件名的变量中包含意外内容-因此,将其打印出来也是一种好习惯。

您的代码包括一些相当旧的样式,因此我用词法范围的FILE1替换了旧的$out全局样式。我还使用了3参数形式的open,从安全角度来看,这是一个更好的主意。

print调用也可能失败(例如:如果磁盘已装满)。这种可能性较小,并且经常忽略检查print的返回值。 close调用也可能失败(例如:在关闭文件句柄之前,输出缓冲区可能不会刷新,然后类似磁盘已满的情况可能会触发失败)。

记住在所有I / O函数调用的末尾添加or die "... $!"有点乏味,因此更好的方法是在您的开始时将autodie杂注添加到样板中脚本。然后,您可以省略显式错误检查,autodie模块将为您生成消息:

use strict;
use warnings;
use autodie;

my($file1,  $file2) = @ARGV;
open my $out, '>>',  $file1;
open my $in,  '<',   $file2;
while (<$in>) {
    print $out $_;
}

close($in);
close($out); 

来自autodie的典型消息可能是:

Can't open '/etc/shadow' for reading: 'Permission denied' at ./ptst.pl line 8

这将告诉您哪个操作失败,参数是什么以及失败的原因。因此,通过使用autodie,您会得到很好的错误消息,而工作量更少。

答案 1 :(得分:0)

尝试使用此版本以获取错误消息:

open(FILE1,">>", $file1) or die $!;
open(FILE2, "<", $file2) or die $!;