Есть код, который порождает child'ов, которые в свою очередь вызывают команду через system/exec/``. Родитель в некоторый момент убивает потомков, при этом вызванная команда продолжает работать, что не есть хорошо. Ближе к коду, задача скрипта: считать урлы из файла и запустить рекурсивную скачку wget'ом, по достижении лимита загруженных страниц - прервать закачку, сам код (извиняюсь за комменты в С-стиле, решетку ставить неудобно):
| Код | my $file=$ARGV[0]; //в качестве аргумента получаем файл со списком урлов
open URLS, "<$file" or terminate("Can't open URL file $file: $!");
my @threads=();
while (my $url=<URLS>) { chomp $url; next if $url=~/^#/;
my $sitename; $sitename=($url=~/^http:\/\/([^\/]+)/)?$1:$url; mkdir "$cfg{save_dir}/$sitename" or terminate("Can't create directory $cfg{save_dir}/$sitename") if !(-d "$cfg{save_dir}/$sitename");
while(scalar @threads>=$cfg{thread}) //если превышен лимит потомков, проверяем потомки на предмет возможности их завершения { check_thread(); sleep(1); } my @files=`find $cfg{save_dir}/$sitename -type f`; //ищем загруженные файлы if (scalar @files<$cfg{limit}) { my $th=fork(); //порождаем потомка если лимит страниц не достигнут if ($th==0) { start_wget($url); //в потомке запускаем wget exit(1); } elsif (!defined($th)) { terminate("Can't fork child: $!"); } else { push @threads,[$th,$sitename]; //в родителе сохраняем pid } } }
while (scalar(@threads)) //пока есть живой потомок, проверяем { check_thread(); sleep(1); }
exit(0);
sub start_wget { my $url=shift; my $sitename; $sitename=($url=~/^http:\/\/([^\/]+)/)?$1:$url; $url='http://'.$url if $url!~/^http/; system("wget","$url","-nv","-nc","-np","-nH","-rl0","-t5","$cfg{wget}","-P$cfg{save_dir}/$sitename"); }
sub check_thread { for (my $i=0; $i<scalar @threads;++$i) { my $sitename=$threads[$i]->[1]; my @files=`find $cfg{save_dir}/$sitename -type f`; my $nfiles=scalar(@files); debug("Download $nfiles files"); if ($nfiles>=$cfg{limit}||!(kill 0,$threads[$i]->[0])) //проверяем завершились ли потомки, или достигли лимита загруженных страниц { debug("Downloading $sitename finished with $nfiles files"); kill TERM => $threads[$i]->[0]; //убиваем splice(@threads,$i,1); $i--; } } }
|
В итоге имеем, что потомок убит, родитель завершился, а wget продолжает закачку. Пробовал и обратные кавычки, результат тот же. |