loops in perl automated ftp

Discussion in 'Perl Misc' started by banzai, Jan 8, 2009.

  1. banzai

    banzai Guest

    Need help with the following automated ftp script please;

    if (defined ($ftp1)) {
    $ftp1->login($FTP1user,$FTP1password) or LogError("FTP login to
    $FTP1server failed");
    if (defined $FTP1destination){
    $ftp1->cwd($FTP1destination) or LogError("Could not change directory
    to $FTP1destination on $FTP1server");
    }
    $ftp1->binary;
    $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy
    $FileBodyName.tar.gz to $FTP1server");
    $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    $DataTagName.gz to $FTP1server");
    $ftp1->quit;
    } else {
    LogError("FTP open failed to $FTP1server, error code: $!");
    }
    #



    I need to modify the above so that the ftp transfers (put's) are attempted
    up to 5 times in case the remote server does not respond. No time delay
    needed between retries.

    TIA
     
    banzai, Jan 8, 2009
    #1
    1. Advertising

  2. banzai

    Snorik Guest

    On 8 Jan., 11:25, "banzai" <> wrote:
    > Need help with the following automated ftp script please;
    >
    > if (defined ($ftp1)) {
    > $ftp1->login($FTP1user,$FTP1password) or LogError("FTP login to
    > $FTP1server failed");
    > if (defined $FTP1destination){
    > $ftp1->cwd($FTP1destination) or LogError("Could not change directory
    > to $FTP1destination on $FTP1server");
    > }
    > $ftp1->binary;
    > $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy
    > $FileBodyName.tar.gz to $FTP1server");
    > $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    > $DataTagName.gz to $FTP1server");
    > $ftp1->quit;} else {
    >
    > LogError("FTP open failed to $FTP1server, error code: $!");}
    >
    > #
    >
    > I need to modify the above so that the ftp transfers (put's) are attempted
    > up to 5 times in case the remote server does not respond. No time delay
    > needed between retries.
    >
    > TIA


    Why not simply use a counter variable in a while loop?

    my $count = 0;
    while ($count <= 4)
    {
    $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP
    copy $FileBodyName.tar.gz to $FTP1server");
    $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    $DataTagName.gz to $FTP1server");
    $count++;
    }

    ?
     
    Snorik, Jan 8, 2009
    #2
    1. Advertising

  3. ["Followup-To:" header set to comp.lang.perl.misc.]

    Snorik <> wrote:
    > On 8 Jan., 11:25, "banzai" <> wrote:
    >> Need help with the following automated ftp script please;
    >>
    >> if (defined ($ftp1)) {
    >> $ftp1->login($FTP1user,$FTP1password) or LogError("FTP login to
    >> $FTP1server failed");
    >> if (defined $FTP1destination){
    >> $ftp1->cwd($FTP1destination) or LogError("Could not change directory
    >> to $FTP1destination on $FTP1server");
    >> }
    >> $ftp1->binary;
    >> $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy
    >> $FileBodyName.tar.gz to $FTP1server");
    >> $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    >> $DataTagName.gz to $FTP1server");
    >> $ftp1->quit;} else {
    >>
    >> LogError("FTP open failed to $FTP1server, error code: $!");}
    >>
    >> #
    >>
    >> I need to modify the above so that the ftp transfers (put's) are attempted
    >> up to 5 times in case the remote server does not respond. No time delay

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >> needed between retries.
    >>
    >> TIA

    >
    > Why not simply use a counter variable in a while loop?



    Because if the remote server _does_ respond, it will upload the
    same file 5 times when once was enough.

    The solution must somewhere include a test of whether the server
    responded or not.


    > my $count = 0;
    > while ($count <= 4)


    That is an error-prone way to do it.

    foreach my $count ( 0 .. 4 )
    or
    foreach my $count ( 1 .. 5 )

    is much easier to read (and therefore, easier to get right).


    > {
    > $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP
    > copy $FileBodyName.tar.gz to $FTP1server");
    > $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    > $DataTagName.gz to $FTP1server");
    > $count++;
    > }



    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad J McClellan, Jan 8, 2009
    #3
  4. banzai

    Ted Zlatanov Guest

    On Thu, 8 Jan 2009 10:25:54 -0000 "banzai" <> wrote:

    b> $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy $FileBodyName.tar.gz to $FTP1server");
    b> $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy $DataTagName.gz to $FTP1server");

    b> I need to modify the above so that the ftp transfers (put's) are attempted
    b> up to 5 times in case the remote server does not respond. No time delay
    b> needed between retries.

    Each one can be done like so (untested code):

    for (1..5)
    {
    last if $ftp1->put("$FileBodyName.tar.gz");
    LogError("Could not FTP copy $FileBodyName.tar.gz to $FTP1server");
    }

    In other words, do the loop 5 times unless one of the put() calls
    succeeds. If that happens, exit early with `last'.

    Ted
     
    Ted Zlatanov, Jan 8, 2009
    #4
  5. banzai

    banzai Guest

    "Ted Zlatanov" <> wrote in message
    news:...
    > On Thu, 8 Jan 2009 10:25:54 -0000 "banzai" <> wrote:
    >
    > b> $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy
    > $FileBodyName.tar.gz to $FTP1server");
    > b> $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    > $DataTagName.gz to $FTP1server");
    >
    > b> I need to modify the above so that the ftp transfers (put's) are
    > attempted
    > b> up to 5 times in case the remote server does not respond. No time delay
    > b> needed between retries.
    >
    > Each one can be done like so (untested code):
    >
    > for (1..5)
    > {
    > last if $ftp1->put("$FileBodyName.tar.gz");
    > LogError("Could not FTP copy $FileBodyName.tar.gz to $FTP1server");
    > }
    >
    > In other words, do the loop 5 times unless one of the put() calls
    > succeeds. If that happens, exit early with `last'.
    >
    > Ted



    Thanks Ted - looks like a good solution so I will try.
    Snorik, this one suits best I think as your solution ignored exit status (if
    thats the right word in perl) of previous attempt(s) . i.e. if first attempt
    succeeds then no need to retry
     
    banzai, Jan 8, 2009
    #5
  6. banzai

    banzai Guest

    "Ted Zlatanov" <> wrote in message
    news:...
    > On Thu, 8 Jan 2009 10:25:54 -0000 "banzai" <> wrote:
    >
    > b> $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy
    > $FileBodyName.tar.gz to $FTP1server");
    > b> $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    > $DataTagName.gz to $FTP1server");
    >
    > b> I need to modify the above so that the ftp transfers (put's) are
    > attempted
    > b> up to 5 times in case the remote server does not respond. No time delay
    > b> needed between retries.
    >
    > Each one can be done like so (untested code):
    >
    > for (1..5)
    > {
    > last if $ftp1->put("$FileBodyName.tar.gz");
    > LogError("Could not FTP copy $FileBodyName.tar.gz to $FTP1server");
    > }
    >
    > In other words, do the loop 5 times unless one of the put() calls
    > succeeds. If that happens, exit early with `last'.
    >
    > Ted



    Actually, one more question :)

    Could a smiliar 5x loop be put around the whole ftp sequence i.e. login, cwd
    and put so tha the whole process is repeated 5 times if required (not just
    the put) and exit early if the put succeeds
     
    banzai, Jan 8, 2009
    #6
  7. banzai

    Snorik Guest

    On 8 Jan., 16:13, "banzai" <> wrote:
    > "Ted Zlatanov" <> wrote in message
    >
    > news:...
    >
    >
    >
    > > On Thu, 8 Jan 2009 10:25:54 -0000 "banzai" <> wrote:

    >
    > > b> $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy
    > > $FileBodyName.tar.gz to $FTP1server");
    > > b> $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    > > $DataTagName.gz to $FTP1server");

    >
    > > b> I need to modify the above so that the ftp transfers (put's) are
    > > attempted
    > > b> up to 5 times in case the remote server does not respond. No time delay
    > > b> needed between retries.

    >
    > > Each one can be done like so (untested code):

    >
    > > for (1..5)
    > > {
    > > last if $ftp1->put("$FileBodyName.tar.gz");
    > > LogError("Could not FTP copy $FileBodyName.tar.gz to $FTP1server");
    > > }

    >
    > > In other words, do the loop 5 times unless one of the put() calls
    > > succeeds. If that happens, exit early with `last'.

    >
    > > Ted

    >
    > Thanks Ted - looks like a good solution so I will try.
    > Snorik, this one suits best I think as your solution ignored exit status (if
    > thats the right word in perl) of previous attempt(s) . i.e. if first attempt
    > succeeds then no need to retry


    Yes, this is completely right, I forgot about that actually :) Teds
    solution is shorter, without being illegible.
     
    Snorik, Jan 8, 2009
    #7
  8. banzai

    J. Gleixner Guest

    banzai wrote:

    > Actually, one more question :)
    >
    > Could a smiliar 5x loop be put around the whole ftp sequence i.e. login, cwd
    > and put so tha the whole process is repeated 5 times if required (not just
    > the put) and exit early if the put succeeds
    >
    >


    Sure. Why do you think it wouldn't work? Actually, maybe it'd
    be better to figure out why it's failing to work the first time.

    You'll have to exit out of the loop correctly, probably easiest to
    use a label.

    perldoc -f last
     
    J. Gleixner, Jan 8, 2009
    #8
  9. banzai

    Snorik Guest

    On 8 Jan., 15:22, Tad J McClellan <> wrote:
    > ["Followup-To:" header set to comp.lang.perl.misc.]
    >
    >
    >
    > Snorik <> wrote:
    > > On 8 Jan., 11:25, "banzai" <> wrote:
    > >> Need help with the following automated ftp script please;

    >
    > >> if (defined ($ftp1)) {
    > >> $ftp1->login($FTP1user,$FTP1password) or LogError("FTP login to
    > >> $FTP1server failed");
    > >> if (defined $FTP1destination){
    > >> $ftp1->cwd($FTP1destination) or LogError("Could not change directory
    > >> to $FTP1destination on $FTP1server");
    > >> }
    > >> $ftp1->binary;
    > >> $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy
    > >> $FileBodyName.tar.gz to $FTP1server");
    > >> $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy
    > >> $DataTagName.gz to $FTP1server");
    > >> $ftp1->quit;} else {

    >
    > >> LogError("FTP open failed to $FTP1server, error code: $!");}

    >
    > >> #

    >
    > >> I need to modify the above so that the ftp transfers (put's) are attempted
    > >> up to 5 times in case the remote server does not respond. No time delay

    >
    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >
    > >> needed between retries.

    >
    > >> TIA

    >
    > > Why not simply use a counter variable in a while loop?

    >
    > Because if the remote server _does_ respond, it will upload the
    > same file 5 times when once was enough.
    >
    > The solution must somewhere include a test of whether the server
    > responded or not.


    You are right, as said elsethread, I did not think of that at all.

    > > my $count = 0;
    > > while ($count <= 4)

    >
    > That is an error-prone way to do it.
    >
    > foreach my $count ( 0 .. 4 )
    > or
    > foreach my $count ( 1 .. 5 )
    >
    > is much easier to read (and therefore, easier to get right).


    Yes, indeed, thanks for pointing that out, I had completely forgotten
    about this possibility.
     
    Snorik, Jan 9, 2009
    #9
  10. banzai

    Ted Zlatanov Guest

    On Thu, 8 Jan 2009 15:18:30 -0000 "banzai" <> wrote:

    b> "Ted Zlatanov" <> wrote in message news:...
    >> On Thu, 8 Jan 2009 10:25:54 -0000 "banzai" <> wrote:
    >>

    b> $ftp1->put("$FileBodyName.tar.gz") or LogError("Could not FTP copy $FileBodyName.tar.gz to $FTP1server");
    b> $ftp1->put("$DataTagName.gz") or LogError("Could not FTP copy $DataTagName.gz to $FTP1server");
    >>

    b> I need to modify the above so that the ftp transfers (put's) are attempted
    b> up to 5 times in case the remote server does not respond. No time delay
    b> needed between retries.
    >>
    >> Each one can be done like so (untested code):
    >>
    >> for (1..5)
    >> {
    >> last if $ftp1->put("$FileBodyName.tar.gz");
    >> LogError("Could not FTP copy $FileBodyName.tar.gz to $FTP1server");
    >> }
    >>
    >> In other words, do the loop 5 times unless one of the put() calls
    >> succeeds. If that happens, exit early with `last'.


    b> Could a smiliar 5x loop be put around the whole ftp sequence i.e. login, cwd
    b> and put so tha the whole process is repeated 5 times if required (not just
    b> the put) and exit early if the put succeeds

    Yes, but then you won't know what failed, and you don't want to do the
    first put 5 times if the second one failed 5 times.

    You probably want to avoid repeating the loop all over your code, which
    is good. I hate repetition too. Perl lets you create anonymous
    subroutines, which are basically a block of executable code you can pass
    as a variable. With those, you can do:

    # untested: try N times to run CODE, and do ERR every time it fails
    sub tryN
    {
    my $N = shift @_;
    my $code = shift @_;
    my $err = shift @_;

    for (1..$N)
    {
    last if $code->();
    $err->();
    }
    }

    # now your program is a bunch of these statements
    tryN(5,
    sub { $ftp1->put("$FileBodyName.tar.gz") },
    sub { LogError("Could not FTP copy $FileBodyName.tar.gz to $FTP1server"); });

    There are some scoping rules at play, but nothing you need to worry
    about with a simple program. You should probably comment this carefully
    if it's going to be used and maintained.

    On Thu, 8 Jan 2009 08:15:27 -0800 (PST) Snorik <> wrote:

    S> Teds solution is shorter, without being illegible.

    I really tried to balance between legible and concise, so I'm glad you
    liked it.

    Thanks
    Ted
     
    Ted Zlatanov, Jan 13, 2009
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stephen Ferg

    Automated Perl to Python translation?

    Stephen Ferg, Sep 4, 2004, in forum: Python
    Replies:
    6
    Views:
    1,259
    John J. Lee
    Sep 8, 2004
  2. D. Buck
    Replies:
    2
    Views:
    527
    D. Buck
    Jun 29, 2004
  3. Me
    Replies:
    2
    Views:
    253
  4. Replies:
    4
    Views:
    275
    Larry
    Feb 18, 2007
  5. Graham Feeley

    Perl Script to be automated

    Graham Feeley, Jul 5, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    232
    Graham Feeley
    Jul 6, 2008
Loading...

Share This Page