Operating System - HP-UX
1821981 Members
3151 Online
109638 Solutions
New Discussion юеВ

Net::FTP multiple file gets

 
SOLVED
Go to solution
jerry1
Super Advisor

Net::FTP multiple file gets

I finally found the line of code to do
multiple file gets with the Net:FTP module.
But, how do you specify a destination to put
the files in, in this line of perl code?
I am not a perl person.

Here is the line of code to get multiple
files, since Net::FTP does not support "prompt"
and "mget" function.

$ftp->get($_) for grep /\.txt/, $ftp->ls ($file);
14 REPLIES 14
Ivan Krastev
Honored Contributor
Solution

Re: Net::FTP multiple file gets

James R. Ferguson
Acclaimed Contributor

Re: Net::FTP multiple file gets

Hi:

To accomplish the equivalent of 'mput' you need to loop over the list (array) of files that you want to 'put'; something like:

for (@files) {
$ftp->put($_)
}

In this example, the name of the file on the remote server will be the same as that on the local server.

The documentation for Net::FTP is useful:

http://search.cpan.org/~gbarr/libnet-1.22/Net/FTP.pm

Regards!

...JRF...
jerry1
Super Advisor

Re: Net::FTP multiple file gets

James, the "destination" is the path
to another directory. I'm doing a mget
not a mput. The line of code only gets and
puts files in the current directory that I
run the perl script from.

I am trying to specify an alternate location
in this line of code.

$ftp->get($_) for grep /\.txt/, $ftp->ls ($file);


James R. Ferguson
Acclaimed Contributor

Re: Net::FTP multiple file gets

Hi (again):

Oh, sorry, I misread "how do you specify a destination to put the files in..." as a question about '[m]put'.

OK, you can simply specify the absolute path:

# $ftp->get($_, "/path/$_") for grep /\.txt/, $ftp->ls ($file);

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Net::FTP multiple file gets

Hi (again):

Actually, rather than add a /path as I first suggested, your script can be better served if you change your local current directory to whatever you want, before you perform the 'get'.

In this way, an argument to the script can later be (optionally) provided to change the directory specification without hardcode.

In any event:

my $local_cwd = "/some/path";
chdir $local_cwd or die "Can't cd to '$local_cwd'\n";
$ftp->get($_) for grep /\.txt/, $ftp->ls ($file);

Regards!

...JRF...
jerry1
Super Advisor

Re: Net::FTP multiple file gets

Well, I found out that I do need to also
use put as you stated in previsous post.
But I do not understand what @files is and
cannot find a reference on how to set it up.

for (@files) {
$ftp->put($_)
}

I tried using ! to get a shell back and
ls the files that need to be put like
in the "get" but that didn't work and
am looking at Net::Cmd but do not understand
the syntax.
James R. Ferguson
Acclaimed Contributor

Re: Net::FTP multiple file gets

Hi (again) Jerry:

> But I do not understand what @files is and
cannot find a reference on how to set it up.

This could look something like:

my @files = $ftp->ls("/home/jerry");
for (@files) {
$ftp->put($_)
}

...which declares a list and populates it with the names of files (and directories) in '/home/jerry'. Then, for every element of the list, a 'put' is performed using each element ($_).

Without the overall script, these are only abstract suggestions for you.

Regards!

...JRF...
jerry1
Super Advisor

Re: Net::FTP multiple file gets

The first part with "get" works fine.
Here is the code:

#!/usr/bin/perl

use strict;
use warnings;
use Net::FTP;
use Net::Netrc;
my $server="dom.com";
my $file="download/*";
my $pageid = "none";
my $pager = "/usr/local/bin/pager";
my $ftpid = "user1";
my $pass = "pass1";
my $local_cwd = "/opt/tools/opsdata.txt/scripts/snet.ftp/aviall/aviall.in";

my $ftp = Net::FTP->new ($server, Timeout => 9000, Debug => 3) or die (exec "$pa
ger $pageid \"$server: ftp cannot connect: $@\"") ;

$ftp->login("$ftpid","$pass") or die (exec "$pager $pageid \"ftp cannot login.\"
") ;

$ftp->binary or die (exec "$pager $pageid \"ftp failed binary mode.\"") ;

chdir $local_cwd or die "Can't cd to '$local_cwd'\n";

## Get multile files if they exist.
$ftp->get($_) for grep /\.txt/, $ftp->ls ($file);

$ftp->quit;

---------------------
The "put" code I cannot get working.
I do not think you can do an "ls" of
the directory from the server you are
initiating the ftp session from while you
are in an ftp session on the remote host:

my @files = $ftp->ls("/home/jerry");

jerry1
Super Advisor

Re: Net::FTP multiple file gets

Here is the "put" script, but it bombs out.

#!/usr/bin/perl

use strict;
use warnings;
use Net::FTP;
use Net::Netrc;
my $server="csdev";
my $pageid = "none";
my $pager = "/usr/local/bin/pager";
my $ftpid = "csdev";
my $pass = "devdev";
my $remote_cwd = "/3rdparty/exostar/test/inbox"
my @files = ls("/opt/tools/opsdata.txt/scripts/snet.ftp/aviall/aviall.out");


my $ftp = Net::FTP->new ($server, Timeout => 9000, Debug => 3) or die (exec "$pa
ger $pageid \"$server: ftp cannot connect: $@\"") ;

$ftp->login("$ftpid","$pass") or die (exec "$pager $pageid \"ftp cannot login.\"
") ;

$ftp->ascii or die (exec "$pager $pageid \"ftp failed binary mode.\"") ;


## Put multile files if they exist.

$ftp->chdir $remote_cwd or die "Can't cd to '$remote_cwd'\n";

for (@files) {
$ftp->put($_);
}

$ftp->quit;

===============================

Scalar found where operator expected at ../putaviall.jc.dev.pl line 33, near "->
chdir $remote_cwd"
(Missing operator before $remote_cwd?)
syntax error at ../putaviall.jc.dev.pl line 21, near "my "
Global symbol "@files" requires explicit package name at ../putaviall.jc.dev.pl
line 21.
syntax error at ../putaviall.jc.dev.pl line 33, near "->chdir $remote_cwd "
Global symbol "@files" requires explicit package name at ../putaviall.jc.dev.pl
line 34.
Execution of ../putaviall.jc.dev.pl aborted due to compilation errors.
James R. Ferguson
Acclaimed Contributor

Re: Net::FTP multiple file gets

HI (again) Jerry:

Here's the guts of your 'put' script amended:

my $local_cwd = '/tmp/dummydir';
my $remote_cwd = '/tmp/mydummydir';

my $ftp = Net::FTP->new ($server, Timeout => 9000, Debug => 3) or
die (exec "$pager $pageid \"$server: ftp cannot connect: $@\"") ;

$ftp->login("$ftpid","$pass") or
die (exec "$pager $pageid \"ftp cannot login.\"
") ;

$ftp->ascii or
die (exec "$pager $pageid \"ftp failed binary mode.\"") ;

## Put multile files if they exist.

$ftp->cwd($remote_cwd) or die "Can't cd to '$remote_cwd'\n";

chdir $local_cwd or die "Can't cd to '$local_cwd'\n";

my @files = $ftp->ls($local_cwd) or die "Can't do 'ls'\n";

for (@files) {
$ftp->put($_) if -f $_;
}

$ftp->quit;

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Net::FTP multiple file gets

Hi (again):

My apologies! I was burned by a bad memory. You care absolutely correct, you cannot do $ftp->ls against the local directory.

This is easy to fix:

my $local_cwd = '/tmp/dummydir';
my $remote_cwd = '/tmp/mydummydir';

my $ftp = Net::FTP->new ($server, Timeout => 9000, Debug => 3) or
die (exec "$pager $pageid \"$server: ftp cannot connect: $@\"") ;

$ftp->login("$ftpid","$pass") or
die (exec "$pager $pageid \"ftp cannot login.\"
") ;

$ftp->ascii or
die (exec "$pager $pageid \"ftp failed binary mode.\"") ;

## Put multile files if they exist.

$ftp->cwd($remote_cwd) or die "Can't cd to '$remote_cwd'\n";

chdir $local_cwd or die "Can't cd to '$local_cwd'\n";

my @files = glob("*");

for (@files) {
$ftp->put($_) if -f $_;
}

$ftp->quit;

Regards!

...JRF...
jerry1
Super Advisor

Re: Net::FTP multiple file gets

It basically works, but the problem is with
this line that is trying to "ls" the remote
server directory and not the local server
directory. Should it not be some kind of
local "ls" like with "chdir" in the line:

chdir($local_cwd) or die "Can't cd to '$local_cwd'\n";

without the "$ftp->" in front of "ls" or
something?


Here is the line that is trying to do a
remote listing of a path that only exists
on the local server and the ftp output below:

my @files = $ftp->ls($local_cwd) or die "Can't do 'ls'\n";


Net::FTP=GLOB(0x40012d58)>>> CWD /3rdparty/exostar/test/inbox
Net::FTP=GLOB(0x40012d58)<<< 250 CWD command successful.
Net::FTP=GLOB(0x40012d58)>>> PORT 10,40,167,52,214,72
Net::FTP=GLOB(0x40012d58)<<< 200 PORT command successful.
Net::FTP=GLOB(0x40012d58)>>> NLST /opt/tools/opsdata.txt/scripts/snet.ftp/aviall
/aviall.out
Net::FTP=GLOB(0x40012d58)<<< 550 /opt/tools/opsdata.txt/scripts/snet.ftp/aviall/
aviall.out: No such file or directory.
Can't do 'ls'
Net::FTP=GLOB(0x40012d58)>>> QUIT
James R. Ferguson
Acclaimed Contributor

Re: Net::FTP multiple file gets

Hi:

...read my last post. Again, I apologize for relying on my faulty memory :-{{

...JRF...
jerry1
Super Advisor

Re: Net::FTP multiple file gets

James, YOU ARE THE MAN!!

Thank you so much. I would have never
figured that last part out.

It was timming on posting. I had not seen
your last post yet while I was messing with
the code.

Many thanks again.