Ahamed Ullah
Ahamed Ullah

Reputation: 11

Perl external command execution error

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.

Upvotes: 1

Views: 2090

Answers (4)

mob
mob

Reputation: 118595

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";

Upvotes: 2

bot403
bot403

Reputation: 2162

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;

Upvotes: 1

TLP
TLP

Reputation: 67900

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.

Upvotes: 0

snoofkin
snoofkin

Reputation: 8895

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

Upvotes: 2

Related Questions