Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

NET::FTP 1

Status
Not open for further replies.

fmuquartet

Programmer
Sep 21, 2006
60
US
I am wanting to retrieve a remote file and store it locally using NET::FTP, but I am getting the error "Cannot open Local file /tmp/file.zip: No such file or directory."

Have I missed something?

Script:

my $ftp_server = 'somehost.com';
my $ftp_userid = 'user';
my $ftp_passwd = 'pass';
my $ftp_from_dir = '/zip';
my $ftp_to_dir = ' /tmp';
my $file = '';
my $ftpConnection = Net::FTP->new($ftp_server, Debug => 1);

if (!$ftpConnection->login($ftp_userid,$ftp_passwd)) {
$logger->error("FTP failed: Could not login\n");
$ftpConnection->quit;
}

$logger->debug("FTP: Logged in to $ftp_server as $ftp_userid\n");
$ftpConnection->binary;

$file="ga01.zip";
getfile($file);
$file="ga01a.zip";
getfile($file);

$ftpConnection->quit;
$logger->info("FTP: Logged out\n");

exit;


sub getfile {
my $file = shift @_;
if ($ftpConnection->get("$ftp_from_dir/$file","$ftp_to_dir/$file")) {
$logger->info("Downloading $file Successful\n");
} else {
$logger->error("Downloading $file Failed\n");
$ftpConnection->quit;
return 2;
}
}
 
does it really say file.zip or is that an example?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Travs69,
File.zip is an example of the real file name being reported.
 
fmuquartet said:
"Cannot open Local file /tmp/file.zip: No such file or directory."

Well, the most obvious question is: Do you have write permissions to the /tmp/ directory or to the /tmp/file.zip file? Does the /tmp/ directory even exist?

- Miller
 
Miller yes, '/tmp' exist, I able to touch /tmp/foo just fine as the same user I am running the script as --this is the confusing part.
 
Well, the secondary question purely based off the error: are you sure that it's writable?

Take the following code and throw it at the beginning of your script to make sure.

Code:
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]IO::Handle[/green][red];[/red]

[black][b]use[/b][/black] [green]strict[/green][red];[/red]

[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$file[/blue] = [red]'[/red][purple]/tmp/file.zip[/purple][red]'[/red][red];[/red]
[url=http://perldoc.perl.org/functions/open.html][black][b]open[/b][/black][/url][red]([/red][black][b]my[/b][/black] [blue]$fh[/blue], [red]'[/red][purple]>[/purple][red]'[/red], [blue]$file[/blue][red])[/red] or [url=http://perldoc.perl.org/functions/die.html][black][b]die[/b][/black][/url] [red]"[/red][purple]Can't open [blue]$file[/blue]: [blue]$![/blue][/purple][red]"[/red][red];[/red]
[blue]$fh[/blue]->[maroon]print[/maroon][red]([/red][red]"[/red][purple]Hello Bob[/purple][red]"[/red][red])[/red] or [black][b]die[/b][/black] [red]"[/red][purple]Can't print: [blue]$![/blue][/purple][red]"[/red][red];[/red]
[blue]$fh[/blue]->[maroon]close[/maroon][red]([/red][red])[/red] or [black][b]die[/b][/black] [red]"[/red][purple]Can't close: [blue]$![/blue][/purple][red]"[/red][red];[/red]

[fuchsia]1[/fuchsia][red];[/red]

[teal]__END__[/teal]
[tt]------------------------------------------------------------
Pragmas (perl 5.8.8) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[/ul]
Core (perl 5.8.8) Modules used :
[ul]
[li]IO::Handle - supply object methods for I/O handles[/li]
[/ul]
[/tt]

- Miller
 
Miller, the problem was whitespace in the variable assignment for '/tmp' . Now that I have this working I am wanting to run this script against four machines with the same ftp accounts, do i need a foreach loop for this or will assigning $ftp_server as '@ftp_servers = qw(server1 server2 server3 server4);' do the job?
 
That'll work. I suggest that you add the $ftp_server to each of your corresponding error messages to make it more obvious what state caused any subsequent error.

- Miller
 
Miller,
It appears I am have problems instatiating the object for a connection with this line 'my $ftpConnection = Net::FTP->new(@ftp_servers, Debug => 1);' I get this error:
Can't call method "login" on an undefined value at ./getga01files line 39.

I even tried replacing @ftp_servers with $ftp_servers .
 
You need to add error checking to your connection phase. if you look at the Net::FTP docs, they normally have trapping for every step of the ftp process. This is always a good idea.

Anyway, based off your original script this is what I would put together. Note this is untested obviously.

Code:
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]Net::FTP[/green][red];[/red]

[black][b]use[/b][/black] [green]strict[/green][red];[/red]

[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]@servers[/blue] = [red]qw([/red][purple]somehost.com foo.com bar.com[/purple][red])[/red][red];[/red]
[black][b]my[/b][/black] [blue]$ftp_userid[/blue] = [red]'[/red][purple]user[/purple][red]'[/red][red];[/red]
[black][b]my[/b][/black] [blue]$ftp_passwd[/blue] = [red]'[/red][purple]pass[/purple][red]'[/red][red];[/red]
[black][b]my[/b][/black] [blue]$ftp_from_dir[/blue] = [red]'[/red][purple]/zip[/purple][red]'[/red][red];[/red]
[black][b]my[/b][/black] [blue]$ftp_to_dir[/blue] = [red]'[/red][purple]/tmp[/purple][red]'[/red][red];[/red]

[maroon]SERVER[/maroon][maroon]:[/maroon]
[olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$server[/blue] [red]([/red][blue]@servers[/blue][red])[/red] [red]{[/red]
	[black][b]my[/b][/black] [blue]$ftp[/blue] = Net::FTP->[maroon]new[/maroon][red]([/red][blue]$ftp_server[/blue], [purple]Debug[/purple] => [fuchsia]1[/fuchsia][red])[/red]
		or [url=http://perldoc.perl.org/functions/die.html][black][b]die[/b][/black][/url] [red]"[/red][purple]Cannot connect to [blue]$ftp_server[/blue]: [blue]$@[/blue][/purple][red]"[/red][red];[/red]

	[blue]$ftp[/blue]->[maroon]login[/maroon][red]([/red][blue]$ftp_userid[/blue], [blue]$ftp_passwd[/blue][red])[/red]
		or [url=http://perldoc.perl.org/functions/do.html][black][b]do[/b][/black][/url] [red]{[/red][blue]$logger[/blue]->[maroon]error[/maroon][red]([/red][red]"[/red][purple]Cannot login [blue]$server[/blue]: [/purple][red]"[/red], [blue]$ftp[/blue]->[maroon]message[/maroon][red])[/red][red];[/red] [olive][b]next[/b][/olive] SERVER[red]}[/red][red];[/red]

	[blue]$logger[/blue]->[maroon]debug[/maroon][red]([/red][red]"[/red][purple]FTP: Logged in to [blue]$ftp_server[/blue] as [blue]$ftp_userid[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red])[/red][red];[/red]
	[blue]$ftp[/blue]->[maroon]binary[/maroon][red];[/red]

	[maroon]FILE[/maroon][maroon]:[/maroon]
	[olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$file[/blue] [red]([/red][red]qw([/red][purple]ga01.zip ga01a.zip[/purple][red])[/red][red])[/red] [red]{[/red]
		[olive][b]if[/b][/olive] [red]([/red][blue]$ftp[/blue]->[maroon]get[/maroon][red]([/red][red]"[/red][purple][blue]$ftp_from_dir[/blue]/[blue]$file[/blue][/purple][red]"[/red],[red]"[/red][purple][blue]$ftp_to_dir[/blue]/[blue]$file[/blue][/purple][red]"[/red][red])[/red][red])[/red] [red]{[/red]
			[blue]$logger[/blue]->[maroon]info[/maroon][red]([/red][red]"[/red][purple]Downloading [blue]$file[/blue] Successful[purple][b]\n[/b][/purple][/purple][red]"[/red][red])[/red][red];[/red]
		[red]}[/red] [olive][b]else[/b][/olive] [red]{[/red]
			[blue]$logger[/blue]->[maroon]error[/maroon][red]([/red][red]"[/red][purple]get failed [/purple][red]"[/red], [blue]$ftp[/blue]->[maroon]message[/maroon][red];[/red][red])[/red][red];[/red]
			[olive][b]next[/b][/olive] SERVER[red];[/red]
		[red]}[/red]
	[red]}[/red]

	[blue]$ftp[/blue]->[maroon]quit[/maroon][red];[/red]
	[blue]$logger[/blue]->[maroon]info[/maroon][red]([/red][red]"[/red][purple]FTP: Logged out[purple][b]\n[/b][/purple][/purple][red]"[/red][red])[/red][red];[/red]
[red]}[/red]

[url=http://perldoc.perl.org/functions/exit.html][black][b]exit[/b][/black][/url][red];[/red]

[fuchsia]1[/fuchsia][red];[/red]

[teal]__END__[/teal]
[tt]------------------------------------------------------------
Pragmas (perl 5.8.8) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[/ul]
Core (perl 5.8.8) Modules used :
[ul]
[li]Net::FTP - FTP Client class[/li]
[/ul]
[/tt]

- Miller
 
Miller,
Ok here is my final version of the ftp script, however I have run into a small problem and need some insight on handling the situation.

I need a way to tell the script to any grab file with the name, 'fr01 fr01a fr02 fr02a fr03 fr03a' end in zip, since these are zipped files i am grabbing.

Script:
use strict;
use warnings;

use Net::FTP;
use Log::Log4perl qw:)easy);
use vars qw($path $timestamp);

my $me = $0; # Editing $0 is unportable
$me =~ s,.*/,,;

my $log_conf = "$me.logconf";
Log::Log4perl::init($log_conf);
my $logger = get_logger();
$logger->info("$me ($$) application started\n");


my @servers = qw(server1 server2 server3);
my $ftp_userid = 'user';
my $ftp_passwd = 'pass';
my $ftp_from_dir = '/foo';
my $ftp_to_dir = '/tmp';
my $ftp_server = ' ';
my @files = qw(fr[0-4]a.zip);

SERVER:
foreach my $ftp_server (@servers) {
my $ftp = Net::FTP->new($ftp_server, Debug => 1)
or die "Cannot connect to $ftp_server: $@";

$ftp->login($ftp_userid, $ftp_passwd)
or do {$logger->error("Cannot login $ftp_server: ", $ftp->message); next SERVER};

$logger->debug("FTP: Logged in to $ftp_server as $ftp_userid\n");
$ftp->binary;

FILE:
foreach my $file (@files) {
if ($ftp->get("$ftp_from_dir/$file","$ftp_to_dir/$file")) {
$logger->info("Downloading $file Successful\n");
} else {
$logger->info("get failed ", $ftp->message);
next SERVER;
}
}

$ftp->quit;
$logger->info("FTP: Logged out\n");
}

exit;

1;
 
my @files = qw(fr01.zip fr01a.zip fr02.zip fr02a.zip fr03.zip fr03a.zip);


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Here's how I would suggest that you take those filenames into account. Note that I've cleaned up your code a little. Feel free to keep or discard at your whim.

Code:
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]File::Basename[/green] [red]qw([/red][purple]basename[/purple][red])[/red][red];[/red]
[black][b]use[/b][/black] [green]File::Spec::Functions[/green] [red]qw([/red][purple]catfile[/purple][red])[/red][red];[/red]
[black][b]use[/b][/black] [green]Log::Log4perl[/green] [red]qw([/red][purple]:easy[/purple][red])[/red][red];[/red]
[black][b]use[/b][/black] [green]Net::FTP[/green][red];[/red]

[black][b]use[/b][/black] [green]strict[/green][red];[/red]
[black][b]use[/b][/black] [green]warnings[/green][red];[/red]

[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$exe[/blue] = [maroon]basename[/maroon][red]([/red][blue]$0[/blue][red])[/red][red];[/red]

[black][b]my[/b][/black] [blue]$log_conf[/blue] = [red]"[/red][purple][blue]$exe[/blue].logconf[/purple][red]"[/red][red];[/red]
[maroon]Log::Log4perl::init[/maroon][red]([/red][blue]$log_conf[/blue][red])[/red][red];[/red]
[black][b]my[/b][/black] [blue]$logger[/blue] = [maroon]get_logger[/maroon][red]([/red][red])[/red][red];[/red]
[blue]$logger[/blue]->[maroon]info[/maroon][red]([/red][red]"[/red][purple][blue]$exe[/blue] ([blue]$$)[/blue] application started[purple][b]\n[/b][/purple][/purple][red]"[/red][red])[/red][red];[/red]

[black][b]my[/b][/black] [blue]@servers[/blue] = [red]qw([/red][purple]server1 server2 server3[/purple][red])[/red][red];[/red]
[black][b]my[/b][/black] [blue]$user[/blue] = [red]'[/red][purple]user[/purple][red]'[/red][red];[/red]
[black][b]my[/b][/black] [blue]$pass[/blue] = [red]'[/red][purple]pass[/purple][red]'[/red][red];[/red]

[black][b]my[/b][/black] [blue]$remote_dir[/blue] = [red]'[/red][purple]/foo[/purple][red]'[/red][red];[/red]
[black][b]my[/b][/black] [blue]$local_dir[/blue] = [red]'[/red][purple]/tmp[/purple][red]'[/red][red];[/red]
[black][b]my[/b][/black] [blue]$files_re[/blue] = [red]qr{[/red][purple]^fr[purple][b]\d[/b][/purple]+a?[purple][b]\.[/b][/purple]zip$[/purple][red]}[/red][red];[/red]

[maroon]SERVER[/maroon][maroon]:[/maroon]
[olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$host[/blue] [red]([/red][blue]@servers[/blue][red])[/red] [red]{[/red]
	[black][b]my[/b][/black] [blue]$ftp[/blue] = Net::FTP->[maroon]new[/maroon][red]([/red][blue]$host[/blue], [purple]Debug[/purple] => [fuchsia]1[/fuchsia][red])[/red]
		or [url=http://perldoc.perl.org/functions/do.html][black][b]do[/b][/black][/url] [red]{[/red][blue]$logger[/blue]->[maroon]error[/maroon][red]([/red][red]"[/red][purple]Cannot connect to [blue]$host[/blue]: [blue]$@[/blue][/purple][red]"[/red][red])[/red][red];[/red] [olive][b]next[/b][/olive] SERVER[red];[/red][red]}[/red][red];[/red]

	[blue]$ftp[/blue]->[maroon]login[/maroon][red]([/red][blue]$user[/blue], [blue]$pass[/blue][red])[/red]
		or [black][b]do[/b][/black] [red]{[/red][blue]$logger[/blue]->[maroon]error[/maroon][red]([/red][red]"[/red][purple]Cannot login [blue]$host[/blue]: [/purple][red]"[/red], [blue]$ftp[/blue]->[maroon]message[/maroon][red])[/red][red];[/red] [olive][b]next[/b][/olive] SERVER[red];[/red][red]}[/red][red];[/red]

	[blue]$ftp[/blue]->[maroon]binary[/maroon][red];[/red]

	[blue]$ftp[/blue]->[maroon]cwd[/maroon][red]([/red][blue]$remote_dir[/blue][red])[/red]
		or [black][b]do[/b][/black] [red]{[/red][blue]$logger[/blue]->[maroon]error[/maroon][red]([/red][red]"[/red][purple]Cannot cwd [blue]$host[/blue] /[blue]$remote_dir[/blue]: [/purple][red]"[/red], [blue]$ftp[/blue]->[maroon]message[/maroon][red])[/red][red];[/red] [olive][b]next[/b][/olive] SERVER[red];[/red][red]}[/red][red];[/red]

	[blue]$logger[/blue]->[maroon]debug[/maroon][red]([/red][red]"[/red][purple]FTP: Logged in to [blue]$host[/blue] as [blue]$user[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red])[/red][red];[/red]

	[maroon]FILE[/maroon][maroon]:[/maroon]
	[olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$file[/blue] [red]([/red][blue]$ftp[/blue]->[maroon]ls[/maroon][red]([/red][red]"[/red][purple].[/purple][red]"[/red][red])[/red][red])[/red] [red]{[/red]
		[olive][b]next[/b][/olive] [olive][b]if[/b][/olive] [blue]$file[/blue] !~ [blue]$files_re[/blue][red];[/red]
		
		[black][b]my[/b][/black] [blue]$to[/blue] = [maroon]catfile[/maroon][red]([/red][blue]$local_dir[/blue], [blue]$file[/blue][red])[/red][red];[/red]
		[blue]$logger[/blue]->[maroon]warn[/maroon][red]([/red][red]"[/red][purple]File already exists: [blue]$to[/blue][/purple][red]"[/red][red])[/red] [olive][b]if[/b][/olive] [url=http://perldoc.perl.org/functions/-X.html][black][b]-e[/b][/black][/url] [blue]$to[/blue][red];[/red]
			
		[olive][b]if[/b][/olive] [red]([/red][blue]$ftp[/blue]->[maroon]get[/maroon][red]([/red][blue]$file[/blue], [blue]$to[/blue][red])[/red][red])[/red] [red]{[/red]
			[blue]$logger[/blue]->[maroon]info[/maroon][red]([/red][red]"[/red][purple]Downloading [blue]$file[/blue] Successful[purple][b]\n[/b][/purple][/purple][red]"[/red][red])[/red][red];[/red]
		[red]}[/red] [olive][b]else[/b][/olive] [red]{[/red]
			[blue]$logger[/blue]->[maroon]info[/maroon][red]([/red][red]"[/red][purple]Cannot get [blue]$file[/blue]: [/purple][red]"[/red], [blue]$ftp[/blue]->[maroon]message[/maroon][red])[/red][red];[/red]
		[red]}[/red]
	[red]}[/red]

	[blue]$ftp[/blue]->[maroon]quit[/maroon][red];[/red]

	[blue]$logger[/blue]->[maroon]info[/maroon][red]([/red][red]"[/red][purple]FTP: Logged out[purple][b]\n[/b][/purple][/purple][red]"[/red][red])[/red][red];[/red]
[red]}[/red]

[fuchsia]1[/fuchsia][red];[/red]

[teal]__END__[/teal]
[tt]------------------------------------------------------------
Pragmas (perl 5.8.8) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[li]warnings - Perl pragma to control optional warnings[/li]
[/ul]
Core (perl 5.8.8) Modules used :
[ul]
[li]File::Basename - Parse file paths into directory, filename and suffix.[/li]
[li]File::Spec::Functions - portably perform operations on file names[/li]
[li]Net::FTP - FTP Client class[/li]
[/ul]
Other Modules used :
[ul]
[li]Log::Log4perl[/li]
[/ul]
[/tt]

- Miller
 
Miller, for some reason 'my $files_re = qr{^fr\d+a?\.zip$};' is not matching the files in the directory, as the script is not downloading anything other than logging in and doing an 'ls' on the cwd.
 
Miller, I modified the regex as follows and everything seems to work:

REGEX:
(\w{2}\d{2}\w.\w{3})

Many thanks on your diligence concerning the matter!
 
Hi Miller,

I like your code layout and highlighting; did you do that by hand or do you have a script that produces the TGML code from Perl code?

Mike

When working on any project the value of other people is exactly that - they are other people. The mismatch between their views and the view you've been contentedly assuming is right, is where that value lies.
 
Nice... Thank you Travis.

Mike

When working on any project the value of other people is exactly that - they are other people. The mismatch between their views and the view you've been contentedly assuming is right, is where that value lies.
 
Who does the e-pixs website, and that page, belong to?

Mike

When working on any project the value of other people is exactly that - they are other people. The mismatch between their views and the view you've been contentedly assuming is right, is where that value lies.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top