本文介绍了为什么当我用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进程时,它会挂起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 17:56