在perl脚本的循环结构中,我编写了以下行来使用系统工具解析文本文件,在进程中生成临时文本文件,然后将临时输出读入数组以便在perl脚本中进行处理:
system("awk '(NR+2)%4==0' $infile[$i+$j] | tre-agrep -ns -E $dist[$a][$b] -k $query[$a][$b] | awk 'BEGIN{FS=\":\";OFS=\":\"}{print \$1,\$2}' > $outfile");
open(my $FH, "<", $outfile) || die "Can't open $outfile: $!";
while(<$FH>) {
...
}
close($FH);
这些命令几乎逐字地重复两次(修改了一些参数,但是文件句柄的循环),循环结构本身被多次迭代。出乎意料地并且看似随意,程序有时无法完成系统调用,导致依赖于系统调用生成的输出的后续行依次失败,触发脚本中止并显示相当无用的错误消息“没有这样的文件或目录“(参考open
语句)。直接从控制台而不是在perl脚本的上下文中执行相同的系统调用会显示该命令产生预期的输出。我将此行为称为任意行为,因为有时我的脚本将在open
行失败之前以各种方式完成1到3次迭代,并且不同成功的基础尚不清楚。当脚本正常工作时,系统调用需要相当长的时间(大约2分钟),而当它失败时,程序会在不到一秒的时间内移动到以下open
行。因此,我想弄清楚为什么有时会跳过系统调用。
脚本在bash shell会话中运行,脚本标题中包含以下内容:
#! /usr/bin/perl
use warnings;
use strict;
答案 0 :(得分:2)
我从根本上同意@ThisSuitIsBlackNot。但是,不知道tre-agrep
是什么,将该部分转换为直接Perl很困难。
那说,至少,为什么不跳过输出文件的生成并直接从Perl读取Unix输出?
open my $FH, '-|', "awk '(NR+2)%4==0' $infile[$i+$j] | " .
"tre-agrep -ns -E $dist[$a][$b] -k $query[$a][$b]" or die "$!";
while (<$FH>) {
chomp;
my ($field1, $field2) = split /:/, $_, 2;
}
close $FH;
在最糟糕的情况下,系统调用的标准输出将是空白的,但这不会影响Perl读取任何内容的能力(因此无效)。
当然,首先执行-e
(存在)调用以确保infile[$i + $j]
不是幽灵并不会有什么坏处。