【发布时间】:2023-03-28 02:26:01
【问题描述】:
在 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 脚本的上下文中执行相同的系统调用表明该命令产生了预期的输出。我将此行为称为任意行为,因为有时我的脚本会完成 1 到 3 次迭代,然后在 open 行失败,并且不同成功的基础尚不清楚。当脚本正常工作时,系统调用需要相当长的时间(大约 2 分钟),而当它失败时,程序会在不到一秒的时间内移动到下面的 open 行。因此,我想弄清楚为什么有时会跳过系统调用。
脚本在 bash shell 会话中运行,脚本头中包含以下内容:
#! /usr/bin/perl
use warnings;
use strict;
【问题讨论】:
-
Perl 内部一般不需要调用
awk; Perl 可以做大部分awk可以做的事情,编写本机 Perl 代码将帮助您避免system()和讨厌的 shell 引用问题。 -
见:the XY problem。这里有很多可能出错的地方;我怀疑被插值的变量可能包含未转义的空格/元字符。如果 system() 确实有问题,则加入
IPC::System::Simple将为您进行所有必要的诊断。我强烈建议您使用有关您尝试解决的问题性质的信息来编辑问题。就像 TheSuitIsBlackNot 所说的那样,一个纯粹的 Perl 解决方案会比你现在做的更简单、更健壮。Text::Fuzzy可以在这里替换 agrep。