Net::FTP調査中

Net::FTPをつかってFTPからファイル情報を取り出すよ。

まず、Net::FTPでFTPに接続。次のようなノリで。

my $ftp = Net::FTP->new($hostname);
$ftp->login($user,$password);

で、$ftp->dirを再帰的に実行する。ls -l形式にマッチする素敵な正規表現はCPANから拝借。

sub print_file {
    my($ftp, $dir) = @_;
    my @files = $ftp->dir()
        or warn "Can't LIST: ", $ftp->message;
    return unless @files;

    print "into $dir\n";

    for (@files) {
        s/\r//g;
        s/\n//g;
        if (/
            ^
            (.|-)                   # (1) type
            (.{9})                  # (2) permittion
            \s+
            (\d+)                   # (3) links
            \s+
            (\w+)                   # (4) owner
            \s+
            (\w+)                   # (5) group
            \s+
            (\d+)                   # (6) size            
            \s+
            (\w{3}\s+\d+\s+\d+:\d+) # (7) date
            \s+
            (.*?)                   # (8) filename
            (?:\s+->\s+(.*))?       # (9) link
            $
            /x)
        {
            print "$dir/$8  $6  $7";
            if ($1 eq 'd') {
                my $next_dir = File::Spec->catfile($dir, $8);
                $ftp->cwd($8);
                &print_file($tree, $ftp, $next_dir);
                $ftp->cdup();
            }
        }
    }
}


ここまで来るのに、なにかとハマったので、ポイント羅列しとこう。

  • $ftp->dirは$ftp->listのラッパー。なにかといろいろやってくれるので$ftp->dirを使う。
  • $ftp->dirの返り値の各行にCRLFついてる(こともある?)
  • $ftp->dirには絶対パスをわたすより、$ftp->cwdでワーキングディレクトリ変えてから相対パス渡す方が良い。