Try to exit inner loop and start next iteration of outter loop.

N

Nene

Hello,

What I'm trying to do is once my inner loop reaches a count of 5, I
want it to exit the while statement and go back to the foreach loop.
But it hangs after it reaches '5' and takes a long time for it go to
to the second iteration (really large files) of the for foreach loop:

#!/usr/bin/perl -w
use strict;

my @LIST = qw/
server_1
server_2
/;

my $count = 0;

FIRST: foreach my $SERVER (@LIST) {

my $ssh = "ssh $SERVER";
my $cmd = "perl -ne 'print' /server/directory/file";


open(SSH, "$ssh $cmd |") || die "ssh: $!";

print "\n";
print "Connected to $SERVER\n";


LINE: while (my $current_line = <SSH>) {
if ($current_line =~ /Failed at the server/) {
$count++;
print "$current_line\n";
next FIRST if $count == 5;
}
}
}
 
X

xhoster

Nene said:
Hello,

What I'm trying to do is once my inner loop reaches a count of 5, I
want it to exit the while statement and go back to the foreach loop.
But it hangs after it reaches '5' and takes a long time for it go to
to the second iteration (really large files) of the for foreach loop:

#!/usr/bin/perl -w
use strict;

my @LIST = qw/
server_1
server_2
/;

my $count = 0;

Don't you want to reset $count for the next server?
FIRST: foreach my $SERVER (@LIST) {

my $ssh = "ssh $SERVER";
my $cmd = "perl -ne 'print' /server/directory/file";

open(SSH, "$ssh $cmd |") || die "ssh: $!";

For Pete's sake indent your code.

What is happening is that when
you re-open SSH, the old handle gets closed. And when a handle from a
piped open gets closed, it waits for the underlying process to exit. It
can take a while for your ssh command to decide you stopped listening to it
and exit.

You could catch the pid from your open and then kill the pid just before
you do the "next FIRST". Or you could make the open do a double-fork by
using the bit of trickery:

open(SSH, "$ssh $cmd & |") || die "ssh: $!";

Or you could by-pass the piped-open "magic" by doing the fork and exec
yourself.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
J

J. Gleixner

Don't you want to reset $count for the next server?


For Pete's sake indent your code.

What is happening is that when
you re-open SSH, the old handle gets closed. And when a handle from a
piped open gets closed, it waits for the underlying process to exit. It
can take a while for your ssh command to decide you stopped listening to it
and exit.

You could catch the pid from your open and then kill the pid just before
you do the "next FIRST". Or you could make the open do a double-fork by
using the bit of trickery:

open(SSH, "$ssh $cmd & |") || die "ssh: $!";

Or you could by-pass the piped-open "magic" by doing the fork and exec
yourself.

Or it'd probably be cleaner to simply move the logic of "printing until
you reach the 5th time /Failed at the server/ happens" to $cmd.

Also, In the original code, there's no difference between using
'next FIRST' and simply 'last'. Neither label is needed.

perldoc -f last
 
T

Tad J McClellan

Nene said:
#!/usr/bin/perl -w


The modern, and much better, way is to use lexical warnings
instead of the command line switch:

#!/usr/bin/perl
use warnings;
 
J

Jürgen Exner

Nene said:
Hello,

What I'm trying to do is once my inner loop reaches a count of 5, I
want it to exit the while statement and go back to the foreach loop.
But it hangs after it reaches '5' and takes a long time for it go to
to the second iteration (really large files) of the for foreach loop:

#!/usr/bin/perl -w
use strict;

my @LIST = qw/
server_1
server_2
/;

my $count = 0;

FIRST: foreach my $SERVER (@LIST) {

my $ssh = "ssh $SERVER";
my $cmd = "perl -ne 'print' /server/directory/file";


open(SSH, "$ssh $cmd |") || die "ssh: $!";

print "\n";
print "Connected to $SERVER\n";


LINE: while (my $current_line = <SSH>) {

Just change this line to

while (my $current_line = <SSH> and $count < 5) {

and you can get rid of those stupid labels.
if ($current_line =~ /Failed at the server/) {
$count++;
print "$current_line\n";
next FIRST if $count == 5;
}
}
}

jue
 
U

Uri Guttman

two things:

JE> Just change this line to

JE> while (my $current_line = <SSH> and $count < 5) {

a guideline i use (and stole from peter scott) is to use the word
booleans (and/or) when doing flow control and the symbolic ones (||, &&)
when doing expressions. their different precedence works better when
they are used that way. the above case is an odd one for that rule as
the binding is better with and (= binds tighter) but it is more of an
expression. as i said, it is a

JE> and you can get rid of those stupid labels.

yes. labels should only be needed in special cases. perl rarely needs
labels and i barely ever use them. they should only be used when
nothing else works well.

uri
 
J

John W. Krahn

Jürgen Exner said:
Just change this line to

while (my $current_line = <SSH> and $count < 5) {

You would have to change that to:

while ( defined( my $current_line = <SSH> ) and $count < 5 ) {

In case <SSH> returned "0".



John
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top