1

I am new to perl and trying to create a FTP script using LFTP program.

I'm trying to execute a FTP script file through LFTP. My code is :

my $CLIENT = "lftp";
my $connectionString =  "" . $CLIENT . " -d -f script.ftp";
my $result = `$connectionString` or die "\nERROR running $CLIENT: $!";
return $result;

Well, it's perfectly execute all command from script.ftp file as debug is on to see the output and after that just die and nothing written to $result.

Error I'm receiving is -

ERROR running lftp: at ftp.pl line 3.

It refers to line where I am passing the output to the variable $result.

Any clue why it's not passing the output to $result and just die?

If I run the same from Linux shell, it's perfectly executing with no error.

1

4 Answers 4

2

Better use an FTP module (such as Net::FTP) rather than counting on shell / external commands.

Sign up to request clarification or add additional context in comments.

3 Comments

The reason for using LFTP is for FTPSSL and SFTP.
so what about Net::SFTP or Net::FTPSSL??
I know I can use them. But, idea is to use this client for all FTP connection type in a single function, just passing the encryption method and port, rather than writing different function for different encryption type.
2

Does the command write anything to standard output (as opposed to standard error)? The return value of backticks is the actual output of the program. If the output is empty, then $result has a "false" value and your die statement gets called.

Some alternatives:

Use system because the return value of system tells you whether the command was successful or not:

system($connectionString) and die "ERROR: running $CLIENT: $?\n"

system("$connectionString > $logFile 2>&1") 
    and die "ERROR in $CLIENT: $?. Look in $logFile\n";

(we use and instead of or because unlike most other functions work, a return value of zero from system means success).

Another option is to join the external command's standard out and standard error so the command succeeds when the only output is "error" output, such as debugging messages:

$result = `$connectionString 2>&1` or die "ERROR: running CLIENT: $!\n";


(edit by popular demand) Another option is to condition on $? (the exit status of the last external command run):

$result = `$connectionString`;
$? == 0  or  die "ERROR: running CLIENT: $! $?\n";

2 Comments

Many thanks. Well, if I run the system() function, it's working perfectly without any error message. But, I need the output log to be saved for generating report. Any idea ?
Run it using the backticks as you were originally to store the output of the command, but afterward check the $? special variable for the actual return code indicating failure or success.
1

The proper way to execute a system command and check for errors would be as follows:

my $result = `$connectionString`;
my $rc = $? >> 8;
if( $rc ){
    die("Error executing command: $!\n");
}else{
    print "Success!\n";
}
return $result;

3 Comments

This is Perl, so the proper way to say that is "A proper way ..."
If I check for error, it returns success. But, nothing is passed to $result. Any idea ??
Does your command actually produce any output to STDOUT? What happens if you run your command from the command line with '2> /dev/null' on the end? If you get no output on the command line your perl program will get nothing in $result either.
0

It's not really an error, you just defined it as an error. The return value of the system call is interpreted by perl as being false, thus triggering the die clause.

4 Comments

It’s not a syscall, it’s a call to the system. :) Anyway, false is the empty string or zero. Wonder which it is? :)
Empty string, zero or undef, rather. I couldn't guess, but if I were him I would check the return value.
Well, I don't know about you, but I think there's a difference between $x = undef, $x = "" and $x = 0.
Then you had better add in (1 == 0), too. When does the madness end? false is the empty string or zero: the buck stops there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.