2010-05-25 4 views
2

У меня есть файл, который выглядит следующим образом:Как создать каталог и извлечь файл по FTP в этот каталог с помощью Perl?

ftp://url1/files1.tar.gz dir1 
ftp://url2/files2.txt dir2 
.... many more... 

То, что я хочу сделать эти шаги:

  1. Создание каталога на основе колонке 2
  2. Unix «CD» в этот каталог
  3. Загрузить файл с 'wget' на основе столбца

Но как этот подход не работает

while(<>) { 
    chomp; 
    my ($url,$dir) = split(/\t/,$_); 
    system("mkdir $dir"); 
    system("cd $dir"); 
    system("wget $url"); # This doesn't get executed 
} 

Каков правильный путь?

ответ

13

Использование решений родной Perl, где это возможно:

  • cd можно сделать с chdir
  • mkdir может быть сделано с mkdir
  • mkdir -p (не умирают, если реж существует, рекурсивное создание) может быть сделано с File::Path, который поставляется с Perl
  • wget может быть сделано с LWP::Simple

Как Я бы это сделал:

use File::Spec::Functions qw(catfile); # adds a '/' between things (or '\' on Windows) 
use LWP::Simple qw(mirror); 
use File::Path qw(mkpath); 
use File::Basename; 
use URI; 

while (<>) { 
    chomp; 
    my ($url, $dir) = split /\t/; 
    mkpath($dir); 

    # Use the 'filename' of the $url to save 
    my $file = basename(URI->new($url)->path); 
    mirror($url, catfile($dir, $file)); 
} 

Если вы сделаете это, вы получите:

  • Переносимость между платформами
  • портативности между оболочками
  • Perl обработка исключений (через возвращаемые значения или die)
  • Perl ввода/вывода (нет необходимости, чтобы избежать ничего)
  • ГИБКОСТЬ в будущем (если вы измените способ вычисления имен файлов или как вы храните веб-контент, или если вы хотите параллельно выполнять веб-запросы)
4

Я расскажу вам один вещь неправильный. system("cd $dir"); создаст суб-оболочку, изменив ее в директорию в пределах, которая будет подчинена, а затем выйдет.

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

Я не уверен, если это ваша конкретная проблема, так как # Fail here немного света на детали :-)

Одно из возможных решений является:

system("mkdir $dir && cd $dir && wget $url"); 

Это будет делать всю партию в одной Sub-shell поэтому не должен страдать от упомянутых проблем.


На самом деле, этот скрипт работает отлично:

use strict; 
use warnings; 
system ("mkdir qwert && cd qwert && pwd && cd .. && rmdir qwert"); 

Выведение:

/home/pax/qwert 
+2

Вероятно, вы должны использовать '&&' вместо ';', на всякий случай, если 'mkdir' или' cd' по какой-то причине не работают. – cjm

+0

Хорошая точка и фиксированная. У нас когда-то был установочный скрипт на HPUX, запущенный как root, который сделал компакт-диск в установочном каталоге, а затем chowned и chmod'ed все под ним для конкретного пользователя и разрешения. К сожалению, мы пропустили каталог установки, скрипт остался в '/', и каждый проклятый файл на коробке был изменен. Ой, вернемся к однопользовательскому режиму мы идем :-) – paxdiablo

+0

@paxdiablo: спасибо. Но, я получил это сообщение об ошибке: 'sh: -c: строка 1: синтаксическая ошибка около неожиданного токена' && ''. – neversaint

Смежные вопросы