1

我正在尝试编写一个调用另一个脚本的 Perl 脚本,该脚本读取整个目录。我没有收到任何错误,但我也没有得到预期的结果。我没有在屏幕上看到任何东西。

我不需要在屏幕上输出任何东西。我在exec()语句中调用的脚本应该将每个图像文件读入DIR目录,并创建一个文件,其中存储从该图像中提取的一些数据。然后,语句中的脚本exec()应该循环,直到读取到目录中的所有图像。

#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use CGI qw/:standard/; 
use CGI::Carp 'fatalsToBrowser';

my $dir = '/FilesToRead/';

my $fichier;
my $ligne;
my $mimetype;
my @listeFichiers;

my $cgi = CGI -> new();

opendir (DIR, $dir) or die "Impossible d'ouvrir $dir: $!";
@listeFichiers = grep {/\.mem$/ && -f "$dir/$_"} readdir (DIR);

while (my $ouvRep = readdir(DIR))
{
    foreach $fichier (@listeFichiers)
    {
        exec "v-file ./param.par ./Picture/$fichier -PM_overflow 3000000" or die "Script perl ne s'est pas execute";
    }
}   
closedir DIR;
4

6 回答 6

8

exec替换当前运行的进程。看

perldoc -f exec

你应该看看

perldoc -f system
于 2009-06-10T18:07:36.037 回答
4

当你使用exec它时,它会用你调用的脚本替换现有的 perl 进程。改为使用system

当'd 脚本结束exec时程序结束。exec在'd 脚本结束system后,原始 perl 脚本继续执行。system

查看这个问题了解更多详情。

于 2009-06-10T18:07:39.610 回答
4

您的代码有两个问题。首先是你使用的逻辑有问题readdir()。第一次使用它时grep(),它会读取整个目录并丢弃任何grep()不匹配的内容。条件中没有其他内容可读取while,因此它在没有单次迭代的情况下退出循环。

第二个问题是您使用exec(). 正如手册页所说

“exec”函数执行一个系统命令并且从不返回——如果你希望它返回,使用system”而不是“exec”。

循环的第一次迭代foreach用 exec'd 命令替换当前进程。v-file如果产生它,你只会得到输出。

我想你的意思是在system()这里使用。

于 2009-06-10T18:09:17.377 回答
2

你写了:

opendir (DIR, $dir) or die "Impossible d'ouvrir $dir: $!";
@listeFichiers = grep {/\.mem$/ && -f "$dir/$_"} readdir (DIR);

while (my $ouvRep = readdir(DIR))

填充@listeFichiers后,readdir(DIR)将使用undef()取决于标量或列表上下文进行响应。因此,您的 while 循环将循环零次。

无论如何,你需要那个while循环做什么?你已经有了你想要的文件列表。如果你决定你真的需要它,那么closediropendir之前

opendir (DIR, $dir) or die "Impossible d'ouvrir $dir: $!";
@listeFichiers = grep {/\.mem$/ && -f "$dir/$_"} readdir (DIR);
closedir DIR;

opendir (DIR, $dir) or die "Impossible d'ouvrir $dir: $!";
while (my $ouvRep = readdir(DIR))

或者您可以rewinddir在第二个while循环之前调用。

opendir (DIR, $dir) or die "Impossible d'ouvrir $dir: $!";
@listeFichiers = grep {/\.mem$/ && -f "$dir/$_"} readdir (DIR);

rewinddir (DIR);

while (my $ouvRep = readdir(DIR))
于 2009-06-10T19:16:47.287 回答
1

exec 调用第一次被击中时,您的进程将被替换。永远不会到达循环的第二次(和后续)迭代。

如果您使用系统(或反引号,如果您想要输出)而不是 exec,它应该做您想要的。您对已经给出的答案具体有哪些不满意的地方?

于 2009-06-10T20:58:01.920 回答
1

我想我会用 fork 来做这件事,也许用Parallel::ForkManager。对于每个项目,您都会派生一个处理它的进程。您可以同时处理几件事情。您不必等待system()完成。如果您只是试图从 CGI 脚本触发它(而不是查看结果等),您甚至可能想要守护调度程序部分,以便它自行处理所有内容,并且 CGI 进程可以在没有它的情况下完成。

您还可以查看IPC::System::Simple以简化进程通信。

于 2009-06-11T01:40:58.027 回答