У меня есть список файлов URL, куда я хочу их скачать:
http://somedomain.com/foo1.gz http://somedomain.com/foo2.gz http://somedomain.com/foo3.gz
Для каждого файла я хочу сделать следующее:
wget
nohup
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 не выполняется должным образом.
Как правильно достичь этого?
Зачем делать это с помощью 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
Если вы хотите параллельную обработку, вы можете сделать это самостоятельно с помощью разветвления или использовать встроенный модуль, чтобы справиться с этим за вас. Попробуйте 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";
Попробуйте объединить команды, используя &&, чтобы вторая выполнялась только после успешного завершения первой.
&&
system("(nohup wget $file && ./myscript.sh $file >> output.txt) &");