Конвейер для загрузки и обработки файлов в среде Unix / Linux с Perl - PullRequest
2 голосов
/ 16 апреля 2010

У меня есть список файлов URL, куда я хочу их скачать:

http://somedomain.com/foo1.gz
http://somedomain.com/foo2.gz
http://somedomain.com/foo3.gz

Для каждого файла я хочу сделать следующее:

  1. Загрузка foo1,2 .. параллельно с wget и nohup.
  2. Каждый раз, когда он завершает загрузку, обрабатывайте их с myscript.sh

Что у меня есть это:

#! /usr/bin/perl

@files = glob("foo*.gz");

foreach $file (@files) {
   my $downurls = "http://somedomain.com/".$file;
   system("nohup wget $file &");
   system("./myscript.sh $file >> output.txt");
}

Проблема в том, что я не могу сказать вышеописанному конвейеру, когда заканчивается загрузка файла. Так что теперь это myscript.sh не выполняется должным образом.

Как правильно достичь этого?

Ответы [ 3 ]

2 голосов
/ 16 апреля 2010

Зачем делать это с помощью perl. вместо этого используйте bash. Ниже приведен только образец.

#!/bin/bash

for file in foo1 foo2 foo3
do
    wget http://samedomain.com/$file.gz .

    if [ -f $file.gz ];
    then
        ./myscript.sh $file.gz >> output.txt
    fi
done
1 голос
/ 16 апреля 2010

Если вы хотите параллельную обработку, вы можете сделать это самостоятельно с помощью разветвления или использовать встроенный модуль, чтобы справиться с этим за вас. Попробуйте Parallel :: ForkManager . Вы можете увидеть немного больше об его использовании в Как я могу управлять пулом вилок в Perl? , но на странице CPAN для модуля будет действительно полезная информация Вы, вероятно, хотите что-то вроде этого:

use Parallel::ForkManager;

my $MAX_PROCESSES = 8; # 8 parallel processes max
my $pm = new Parallel::ForkManager($MAX_PROCESSES);

my @files = glob("foo*.gz");

foreach $file (@all_data) {
  # Forks and returns the pid for the child:
  my $pid = $pm->start and next; 

  my $downurls = "http://somedomain.com/".$file;
  system("wget $file");
  system("./myscript.sh $file >> output.txt");

  $pm->finish; # Terminates the child process
}

print "All done!\n";
1 голос
/ 16 апреля 2010

Попробуйте объединить команды, используя &&, чтобы вторая выполнялась только после успешного завершения первой.

system("(nohup wget $file  && ./myscript.sh $file >> output.txt) &");
...