CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Net::FTP - Returing 'Bad remote filename" error

 



mpride
New User

Dec 28, 2012, 12:41 PM

Post #1 of 3 (985 views)
Net::FTP - Returing 'Bad remote filename" error Can't Post

I'm am not a programmer by any means but I have used Perl to accomplish a few tasks in the past. At the moment I need a script to read file names from a file that I create from an 'ls' command. Then I need it to connect to a remote server and put those file(s) in the remote directory.

When I run the script I get the following error:

# ./ftp_logs2.sh
Bad remote filename '20121221.log
'
at ./ftp_logs2.sh line 33

I have checked the file that I create on line 8 and there are no spaces etc. Here is a sample for the 'filelist' file:

20121221.log
20121222.log
20121223.log


I have also included 'print' statements at times within the script to print the contents of the array and it seems fine. I'm not sure what I'm missing. It's such a simple script but......

Here it is. Please don't kill me for lack of comments and indentation etc.

#!/usr/bin/perl -w
########################################

{

chdir("/var/log/wireless");

system ("find \*.log -type f -mtime +1 >>filelist");

$userid = "memorial\\cw2000";
$password = "g0ldfing3r";

$list = "/var/log/wireless/filelist";
open("list");
@array = <list>;
close("list");
$file = shift(@array);

do

{

use Net::FTP;

$ftp = Net::FTP->new("10.9.80.38");

$ftp->login("$userid", $password)
or die "Cannot login ", $ftp->message;

$ftp->ascii;

$ftp->cwd("/wireless/syslog")
or die "Cannot change working directory ", $ftp->message;

$ftp->put($file);

}

until (@array eq 0);

$ftp->quit;

}

system ("rm -f /var/log/wireless/filelist");


Laurent_R
Enthusiast / Moderator

Dec 28, 2012, 2:59 PM

Post #2 of 3 (981 views)
Re: [mpride] Net::FTP - Returing 'Bad remote filename" error [In reply to] Can't Post


In Reply To
Please don't kill me for lack of comments and indentation etc.


Why should we want to kill you for that? No point, really. You are shooting the bullet into your head yourself, you don't need any help for your suicide, you're doing it yourself very properly and very efficiently...

Otherwise, I have not used the Net::FTP module in ages and don't know if your FTP commands are correct, but I can spot a couple of things that seem wrong or suboptimal to me.

The most important point is that the logic of your loop seems to be wrong:


Code
$file = shift(@array); 
do
{
use Net::FTP;
$ftp = Net::FTP->new("10.9.80.38");
$ftp->login("$userid", $password)
or die "Cannot login ", $ftp->message;
$ftp->ascii;
$ftp->cwd("/wireless/syslog")
or die "Cannot change working directory ", $ftp->message;
$ftp->put($file);
}
until (@array eq 0);


Basically, you are reading the first filename in your array and then only enter the loop that is supposed to stop once the array has been exhausted, which will of course never happen, since you are not reading the array within the loop (unless your array has only one filename).

The right way to do this would be something like this:


Code
foreach my $filename (@array) { 
# do your FTP commands with $filename
# ...
}


A couple of other observations:
- chomp your filenames before you use them when they are obtained from a system command, it is very unlikely to work otherwise;
- put the "use Net::FTP; " statement at the beginning of the script, not within the loop
- the first "{" block opening is useless (and so is the corresponding closing statement)
- don't name your array @array, it is clear it is an array from the sigil (the @ sign at the beginning), give it a name that make sense to your program, such as, say, @list_of_the_names_of_the_files_that_I_want_to_transfer (I am overdoing it somewhat here, but I hope you get the point, @list_of_files would already be much better)
- if you open the FTP connection within the loop, then close it also within the same loop, before opening the next one (but it would probably make more sense to open the FTP connection only once, outside the loop, and handle only the tranfer of each file within the loop, and close the connection at the end).
- there are better ways to list files and remove them that using the "system" command, look at the Perl built-in commands to do that (commands such as "glob", "readdirr, "unlink", etc.).

But, of course, the most serious errors listed above, you probably would have seen immediately if you had taken just a few minutes to indent your code correctly... And you would probably have saved a lot of hours wasted stupidly by usefully spending these few minutes.

;-)


FishMonger
Veteran / Moderator

Dec 29, 2012, 7:21 AM

Post #3 of 3 (974 views)
Re: [mpride] Net::FTP - Returing 'Bad remote filename" error [In reply to] Can't Post

The first problem I noticed was that you didn't include the strict pragma, which should be in every Perl script you write. The strict pragma will require you to declare your vars prior to using them, which is normally done with the 'my' keyword.

The warnings pragma should also be used instead of the -w switch. The switch and pragma do almost the same thing. The key difference is the switch is applied globally and can not be disabled if need be, whereas the pragma is lexically scoped and can be enabled/disabled at the block level.

So, your scripts should always begin like this:

Code
#!/usr/bin/perl 

use strict;
use warnings.


Instead of making a system call to the find command where you redirect its output, it would be more efficient to use Perl's File::Find or File::Find::Rule module to retrieve and store the file list in an array directly without the intermediate step of the external file.

File::Find - http://search.cpan.org/~dom/perl-5.12.5/lib/File/Find.pm
File::Find::Rule - http://search.cpan.org/~rclamp/File-Find-Rule-0.33/lib/File/Find/Rule.pm

Similarly, Instead of the system call to the rm command, you should be using Perl's unlink function.
perldoc -f unlink http://perldoc.perl.org/functions/unlink.html


Quote

Code
open("list"); 
@array = <list>;
close("list");


That is not going to do what you expect and will generate several warnings.

You should use the 3 arg form of open, a lexical var for the filehandle, check the return code to make sure it was successful and take proper action if it wasn't.


Code
open my $file_listing_fh, '<', $list or die "failed to open '$list' $!";



(This post was edited by FishMonger on Dec 29, 2012, 7:22 AM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives