【问题标题】:How can I create a directory and fetch a file over FTP into that directory using Perl?如何使用 Perl 创建一个目录并通过 FTP 将文件提取到该目录中?
【发布时间】:2010-05-25 23:36:15
【问题描述】:

我有一个如下所示的文件:

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

我想要做的是这些步骤:

  1. 根据第 2 列创建目录
  2. Unix 'cd' 到那个目录
  3. 基于 column1 使用“wget”下载文件

但是我的这个方法怎么不行

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

正确的做法是什么?

【问题讨论】:

    标签: perl


    【解决方案1】:

    尽可能使用原生 Perl 解决方案:

    • cd 可以用 chdir 完成
    • mkdir 可以用 mkdir 完成
    • mkdir -p(如果 dir 存在就不要死,递归创建)可以用 Perl 自带的 File::Path 来完成
    • 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));
    }
    

    如果你这样做,你会得到:

    • 平台之间的可移植性
    • shell 之间的可移植性
    • Perl 异常处理(通过返回值或die
    • Perl 输入/输出(无需转义)
    • 未来的灵活性(如果您更改了计算文件名的方式,或者您存储 Web 内容的方式,或者如果您想要并行运行 Web 请求)

    【讨论】:

      【解决方案2】:

      我会告诉你一件事错了。 system("cd $dir"); 将创建一个子shell,进入该子shell的目录,然后退出。

      运行 Perl 的进程仍将在其原始目录中。

      我不确定这是否是您的具体问题,因为 # Fail here 对细节有点了解 :-)

      一种可能的解决方法是:

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

      这将在 one 子外壳中完成所有工作,因此不应遭受上述问题的困扰。


      事实上,这个脚本运行良好:

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

      输出:

      /home/pax/qwert
      

      【讨论】:

      • 你应该使用&amp;&amp;而不是;,以防mkdircd由于某种原因失败。
      • 好点和固定。我们曾经有一个在 HPUX 上以 root 身份运行的安装脚本,它对安装目录执行了 cd,然后对特定用户和权限下的所有内容进行了 chown'ed 和 chmod'ed。不幸的是,我们拼错了安装目录,脚本留在了/,并且盒子上的每个该死的文件都被更改了。糟糕,我们回到单用户模式 ​​:-)
      • @paxdiablo:谢谢。但是,我收到此错误消息:sh: -c: line 1: syntax error near unexpected token &&'`。
      • 然后您可以将&amp;&amp; 替换为;(并牺牲错误检查)。我给出的答案在我的系统上运行良好,所以我不确定你使用的是什么外壳。您可能必须选择特定的 shell,例如 system ("bash -c 'mkdir ... '");
      • 如果您不打算使用 Perl,请不要使用 Perl。只需使用 shell 脚本。 :)
      猜你喜欢
      • 2013-04-30
      • 1970-01-01
      • 2016-08-04
      • 2012-03-01
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 2013-03-03
      • 2015-05-10
      相关资源
      最近更新 更多