本文介绍了为什么当我用Perl的系统调用jzip进程时,它会挂起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我绝对是Perl的新手,如果您觉得这个问题很愚蠢,请原谅。
我正在尝试用Perl(ActivePerl、jzip、Windows XP)中的jzip解压缩一堆.cab文件:
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use IO::File;
use v5.10;
my $prefix = 'myfileprefix';
my $dir = '.';
File::Find::find(
sub {
my $file = $_;
return if -d $file;
return if $file !~ /^$prefix(.*).cab$/;
my $cmd = 'jzip -eo '.$file;
system($cmd);
}, $dir
);
代码解压文件夹中的第一个.cab文件并挂起(没有任何错误)。它会一直挂在那里,直到我按下Ctrl+c停止。有人知道问题出在哪里吗?
编辑:我使用cessxp检查了进程,我发现启动了正确数量的jzip进程(根据位于源文件夹中的CAB文件的数量)。但是,其中只有一个进程在cmd.exe=>Perl下运行,并且这些进程都不会在触发后关闭。在我看来,我需要关闭进程并逐个执行,我不知道如何在Perl中做到这一点。有什么建议吗?
编辑:我还尝试用记事本替换jzip,结果发现它每次打开一个文件(按顺序),只有当我手动关闭记事本时,才会触发另一个实例。这是ActivePerl中的常见行为吗?
编辑:我终于解决了,但我仍然不完全确定为什么。我所做的是删除脚本中的XML库,这不应该是相关的。抱歉,我在开始时故意删除了"use XML::DOM",因为我认为它与这个问题完全无关。旧:用严用严;使用警告;
use File::Find;
use IO::File;
use File::Copy;
use XML::DOM;
use DBI;
use v5.10;
新建:
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use IO::File;
use File::Copy;
use DBI;
use v5.10;
my $prefix = 'myfileprefix';
my $dir = '.';
# retrieve xml file within given folder
File::Find::find(
sub {
my $file = $_;
return if -d $file;
return if $file !~ /^$prefix(.*).cab$/;
say $file;
#say $file or die $!;
my $cmd = 'jzip -eo '.$file;
say $cmd;
system($cmd);
}, $dir
);
但是,这会带来另一个问题,当提取的文件已经存在时,脚本将再次挂起。我高度怀疑这是JZIP的问题,解决问题的另一种方法是简单地将JZIP替换为EXTRACT,就像@ghost dog74下面指出的那样。推荐答案
根据您的编辑,以下是我的建议:
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use IO::File;
use v5.10;
my $prefix = 'myfileprefix';
my $dir = '.';
my @commands;
File::Find::find(
sub {
my $file = $_;
return if -d $file;
return if $file !~ /^$prefix(.*).cab$/;
my $cmd = "jzip -eo $File::Find::name";
push @commands, $cmd;
}, $dir
);
#asynchronously kick off jzips
my $fresult;
for @commands
{
$fresult = fork();
if($fresult == 0) #child
{
`$_`;
}
elsif(! defined($fresult))
{
die("Fork failed");
}
else
{
#no-op, just keep moving
}
}
编辑:添加了异步。编辑2:已修复范围问题。
这篇关于为什么当我用Perl的系统调用jzip进程时,它会挂起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!