Как я могу повторно вызвать другой скрипт? - PullRequest
1 голос
/ 10 июня 2009

Я пытаюсь написать 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;

Ответы [ 6 ]

8 голосов
/ 10 июня 2009

exec заменяет текущий запущенный процесс. См

<a href="http://perldoc.perl.org/functions/exec.html" rel="nofollow noreferrer">perldoc -f exec</a>

Вы должны посмотреть на

<a href="http://perldoc.perl.org/functions/system.html" rel="nofollow noreferrer">perldoc -f system</a>
4 голосов
/ 10 июня 2009

У вас две проблемы с вашим кодом. Во-первых, при использовании readdir() существует логическая проблема. При первом использовании grep() он считывает весь каталог и удаляет все, что не соответствует grep(). В условии while больше нечего читать, поэтому он выходит из цикла без единой итерации.

Вторая проблема связана с использованием exec(). Как говорится в справочной странице 1017 *

Функция "exec" выполняет системную команду и никогда не возвращается - используйте system "вместо" exec ", если вы хотите, чтобы она возвращалась.

Первая итерация вашего цикла foreach заменяет текущий процесс командой exec'd. Вы получите результат, только если v-file его выдаст.

Я думаю, вы хотите использовать system() здесь.

4 голосов
/ 10 июня 2009

когда вы используете exec, заменяет существующий процесс perl на вызванный вами скрипт. Вместо этого используйте system.

При exec программа заканчивается, когда заканчивается скрипт exec 'd. При system оригинальный сценарий perl продолжается после завершения сценария system 'd.

Посмотрите на этот вопрос для более подробной информации.

2 голосов
/ 10 июня 2009

Вы писали:

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? У вас уже есть список файлов, которые вы хотите. Если вы решите, что вам это действительно нужно, то closedir и opendir до того, как

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))
1 голос
/ 11 июня 2009

Я думаю, я бы сделал это с помощью fork, возможно, с Parallel :: ForkManager . Для каждого элемента вы создаете процесс, который его обрабатывает. Вы можете обрабатывать несколько вещей одновременно. Вам не нужно ждать, пока system() закончится. Если вы просто пытаетесь вызвать это из CGI-скрипта (вместо того, чтобы видеть результаты и т. Д.), Вы можете даже захотеть демонизировать часть диспетчера, чтобы она выполнялась сама по себе для обработки всего, и процесс CGI может завершиться без него.

Вы также можете взглянуть на IPC :: System :: Simple для упрощения процесса взаимодействия.

1 голос
/ 11 июня 2009

При первом обращении к exec-вызову ваш процесс будет заменен. Вторая (и последующие) итерации цикла никогда не будут достигнуты.

Если вы используете system (или backticks, если вы хотите вывод) вместо exec, он должен делать то, что вы хотите. Что конкретно в ответах уже дают, вы не удовлетворены?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...