tags:

views:

227

answers:

6

Hi all, I'm trying to write a Perl script that calls another script, that reads an entire directory. I don't get any errors, but i don't get the expected result either. I don't get anything on the screen.

I don't need to output anything on screen. The script I'm calling in the exec() statement should read each image file into the DIR directory, and create a file where it stores some data extracted from that image. The script in the exec() statement should then loop until all images into the directory are read.

#!/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;
+8  A: 

exec replaces the currently running process. See

perldoc -f exec

You should look at

perldoc -f system
Sinan Ünür
+4  A: 

when you use exec it replaces the existing perl process with the script you called. Use system instead.

With exec the program ends when the exec'd script ends. With system the original perl script continues after the system'd script ends.

Look at this question for more details.

Nathan Fellman
Or back ticks `system request`
Copas
yes, or open with a pipe
Nathan Fellman
+4  A: 

You have two problems with your code. The first is there is a logic problem in your use of readdir(). The first time you use it, with grep(), it reads in the entire directory and discards anything that grep() doesn't match. There is nothing else to read in the while condition, so it exits the loop without a single iteration.

The second problem is with your use of exec(). As the man page says

The "exec" function executes a system command and never returns-- use system" instead of "exec" if you want it to return.

The first iteration of your foreach loop replaces the current process with the exec'd command. You'll only get output if v-file produces it.

I think you mean to use system() here.

Steve Madsen
+2  A: 

You wrote:

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

while (my $ouvRep = readdir(DIR))

Once you populate @listeFichiers, readdir(DIR) will then respond with undef or () depending on scalar or list context. So, your while loop will loop zero times.

What do you need that while loop for anyway? You already have the list of files you want. If you decide you really need it, then closedir and opendir before while

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))

Or you could call rewinddir before the second while loop.

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

rewinddir (DIR);

while (my $ouvRep = readdir(DIR))
glenn jackman
That would be a SAQ: perldoc -f rewinddir. perldoc perlfunc lists all perl functions.
Sinan Ünür
+1  A: 

The very first time that exec call gets hit, your process will be replaced. The second (and subsequent) iterations of the loop will never be reached.

If you use system (or backticks if you want output) instead of exec, it should do what you want. What specifically about the answers already give aren't you satisfied with?

Chris Simmons
+1  A: 

I think I'd do this with fork, perhaps with Parallel::ForkManager. For every item you fork a process which handles it. You can process several things at the same time. You don't have to wait for system() to finish. If you are merely trying to trigger this from a CGI script (rather than see results, etc), you might even want to daemonize the dispatcher portion so it goes off on its own to process everything and the CGI process can finish without it.

You might also look at IPC::System::Simple for easy process communication.

brian d foy