aullah has asked for the wisdom of the Perl Monks concerning the following question:

Hi, 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 and after that just die and nothing written to $result. Any clue why it's not passing the output to $result and just die? If I run the same from shell, it's perfectly executing with no error.

Replies are listed 'Best First'.
Re: Perl die after executing external program
by mr_mischief (Monsignor) on Apr 28, 2011 at 20:11 UTC

    Backticks don't capture STDERR. You'd need to redirect STDERR on top of STDOUT for lftp as lftp uses STDERR for much of its interface.

    Try this:

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

    I make no guarantees, but I did install lftp just to test this theory and look at this which shows STDERR being used:

    [chris@pineapple ss64]$ >bar [chris@pineapple ss64]$ lftp -d -f foo > bar ---- Resolving host address... ---- 1 address found: 64.131.79.110 Password: [chris@pineapple ss64]$ cat bar [chris@pineapple ss64]$ lftp -d -f foo > bar 2>&1 Password: [chris@pineapple ss64]$ cat bar ---- Resolving host address... ---- 1 address found: 64.131.79.110 [chris@pineapple ss64]$

    As a side note, I hope you're using SFTP or HTTPS (both of which modern versions of lftp support) if you're not using an anonymous connection. I don't use plain-text FTP with authenticated accounts, and I recommend others don't. Without getting into too many specifics about statistics, let's say it's common in the security department of a web hosting company to deal with customers whose hosting account credentials were stolen by malware or sniffing. It may be a small portion of customers who ever have a breach, but compromised passwords are a fairly common sort of breach. Use SFTP or scp if you can, and use HTTPS when possible if logging into a web app you actually care a lot about.

    BTW, none of this is really Perl-specific beyond 'Backticks don't capture STDERR.'. Then again, those backticks are reminiscent of shell backticks which work the same way, so that's not even that Perl-specific.

Re: Perl die after executing external program
by davido (Cardinal) on Apr 28, 2011 at 20:08 UTC

    What should $result contain? Is it possible that the return value is either '0', or an empty string (either of which would evaluate to false, triggering the die.)

    Your writeup states that the external command is executing correctly (if I understand what you're saying). But if it weren't executing correctly I might ask if it's running with the same permissions you have.


    Dave

      Yes, I'm using root account for executing this perl script.
        I see you replied to Re: Perl die after executing external program after I posted Re: Perl die after executing external program but did you bother to read what I typed? You're already capturing STDOUT of the process. You also need to capture STDERR, because that's where the output you want goes.

        Yes, it really is that simple. Differences in account permissions are always a relatively good guess about differences in how programs operate, but a good guess is still a guess. Which file descriptor lftp uses for output doesn't change depending on which account is running the program. Which one you need to capture does change depending on which one is being written to in the executed program.

        2>&1 is your friend.