0

I would like to test files and directories which I downloaded with ftp if they are files or directories. With the code below I always get the else statement (2,4,6) what ever $x is (file or directory). What is wrong with this code?

use Net::FTP;

my $host = "whatever";
my $user = "whatever";
my $password = "whatever";

my $f = Net::FTP->new($host) or die "Can't open $host\n";
$f->login($user, $password) or die "Can't log $user in\n";

# grep all folder of top level
my @content = $f->ls;

# remove . and ..
@content = grep ! /^\.+$/, @content;

foreach my $x (@content) {

    print "\n$x: ";
    if ( -f $x ) {print " ----> (1)";} else {print " ----> (2)";}
    if ( -d $x ) {print " ----> (3)";} else {print " ----> (4)";}
    if ( -e $x ) {print " ----> (5)";} else {print " ----> (6)";}
}
giordano
  • 2,954
  • 7
  • 35
  • 57
  • 2
    Doesn't `ls` simply return a list of file/directory *names*? If so, and those entries don't reside on the local machine the script is running on, the entries won't be a file, they won't be a directory and they won't exist. You need to `get` the data before you can test against it. – stevieb Jan 19 '16 at 18:07
  • 1
    From [Net::FTP's ls() documentation](http://search.cpan.org/~shay/libnet-3.08/lib/Net/FTP.pm): "Get a directory listing of DIR, or the current directory." ...just a listing, not the entities themselves. – stevieb Jan 19 '16 at 18:09
  • 2
    An embarassing thanks! – giordano Jan 19 '16 at 18:39
  • Hey, no worries! It happens to everyone :D – stevieb Jan 19 '16 at 18:40

1 Answers1

4

Per my comments in the OP, ls simply returns a list of names of the entities, it does not fetch them to the local machine. To get files along with directories, you'll need to use Net::FTP::Recursive. Here's an example:

use warnings;
use strict;

use Net::FTP::Recursive;

my $host = 'localhost';
my $user = 'xx';
my $password = 'xx';

my $f = Net::FTP::Recursive->new($host) or die "Can't open $host\n";
$f->login($user, $password) or die "Can't log $user in\n";

my @content = $f->ls;

@content = grep ! /^\.+$/, @content;

# note the rget() below, not just get. It's recursive

$f->rget($_) for @content;

foreach my $x (@content) {

    print "\n$x: ";
    if ( -f $x ) {print " ----> (1)";} else {print " ----> (2)";}
    if ( -d $x ) {print " ----> (3)";} else {print " ----> (4)";}
    if ( -e $x ) {print " ----> (5)";} else {print " ----> (6)";}
}

Example output:

a.txt:  ----> (1) ----> (4) ----> (5)
dir_a:  ----> (2) ----> (3) ----> (5)
stevieb
  • 9,065
  • 3
  • 26
  • 36
  • Thanks. Is it possible to test file and directories without fetch them? The goal of my code was to get a list (txt-file) of directories and files to see in which directories are which files. The problem is that some files don't have extension. Before the appearance of file without extension I could distinguish directory and files with `ls` an `$x =~ /\./` respectively `$x !~ /\./`. – giordano Jan 20 '16 at 09:16