help with pipe

B

bjlockie

Create ./channels.conf with the single line:
CBC:539000000:8VSB:49:52:3


This code never gets to 'here3'.
I think because the command ping never finishes (ping is an example
command, there are no switches to make the real command stop).
I've seen similar code working elsewhere.


my $cmd = 'ping google.ca >/dev/null |';

open( ZAP, $cmd ) || die "can't fork: $!";

print $cmd . "\n";

print "here2\n";

while (my $line = <ZAP>) {
print $line;
}

print "here3\n";
 
J

Jens Thoms Toerring

bjlockie said:
This code never gets to 'here3'.
I think because the command ping never finishes (ping is an example
command, there are no switches to make the real command stop).
I've seen similar code working elsewhere.
my $cmd = 'ping google.ca >/dev/null |';
open( ZAP, $cmd ) || die "can't fork: $!";

You'd nowadays better use the three-argument form of open
and variables for file handles:

my $cmd = 'ping google.ca > /dev/null';
open my $zap, '-|', $cmd or die "can't fork: $!";
print $cmd . "\n";
print "here2\n";
while (my $line = <ZAP>) {
print $line;
}
print "here3\n";

Yes, of course, if ping never finishes, why should the loop
terminate? If you want it to end you must decide on a condi-
tion and implement that. One possibility would be to stop
after a certain number of lines - add a counter that you
increment in the loop and use in the loop condition. Another
condition could be that you only want to read for a certain
time, this could be dealt with with by setting up a timer (e.g.
with the alarm() function) that raises the SIGALRMsignal and
kill the process in the handler for that signal (the PID of
the spawned process is what open returns). Something like

use strict;
use warnings;
my $cmd = 'ping google.ca > /dev/null';
my $pid = open my $zap, '-|', $cmd or die "can't fork: $!";
$SIG{ ALRM } = sub { kill 'TERM', $pid };
print "here2\n";
alarm 3;
while ( my $line = <$zap> ) {
print $line;
}
print "here3\n";

should do the job of getting out of the loop after 3 seconds.
Sorry, without knowing what you want to achieve it's a bit
difficult to be more specific.

Regards, Jens
 
P

Peter J. Holzer

Create ./channels.conf with the single line:
CBC:539000000:8VSB:49:52:3


This code never gets to 'here3'.

Jens already explained that.
I think because the command ping never finishes (ping is an example
command, there are no switches to make the real command stop).
I've seen similar code working elsewhere.


my $cmd = 'ping google.ca >/dev/null |';

open( ZAP, $cmd ) || die "can't fork: $!";

What do you expect to read from the pipe? You have redirected the
standard output (which would normally go to the pipe) to /dev/null.

hp
 
J

Jürgen Exner

bjlockie said:
This code never gets to 'here3'.
I think because the command ping never finishes (ping is an example
command, there are no switches to make the real command stop).
I've seen similar code working elsewhere.


my $cmd = 'ping google.ca >/dev/null |';

open( ZAP, $cmd ) || die "can't fork: $!";

This has nothing to do with fork. A more accurate message would be
"can't run $cmd because $!"
print $cmd . "\n";

print "here2\n";

while (my $line = <ZAP>) {
print $line;
}

print "here3\n";

Well, of course it doesn't. $cmd never terminates, therefore ZAP is
never closed, and therefore the while loop can't terminate either,
because there is always the chance, that after 1000 eternities there
might be output from $cmd.

I am not sure what your goal is here.
If you just want to run the other command while ignoring its output,
then just start it in the background or fork() a new process.
If you want to capture part of the output then you will have to decide
what part of that output is relevant to you: the first x lines, the
first y hours, the first z characters, all output until a certain
pattern, .... and use that as the termination condition for the loop.

jue
 
B

bjlockie

This has nothing to do with fork. A more accurate message would be
"can't run $cmd because $!"





Well, of course it doesn't. $cmd never terminates, therefore ZAP is
never closed, and therefore the while loop can't terminate either,
because there is always the chance, that after 1000 eternities there
might be output from $cmd.

I am not sure what your goal is here.
If you just want to run the other command while ignoring its output,
then just start it in the background or fork() a new process.
If you want to capture part of the output then you will have to decide
what part of that output is relevant to you: the first x lines, the
first y hours, the first z characters, all output until a certain
pattern, .... and use that as the termination condition for the loop.

jue

my $cmd = 'ping google.ca
|';

open( ZAP, $cmd ) || die "can't fork:
$!";

print $cmd .
"\n";

print
"here2\n";

my $numLines =
0;

while (($numLines < 10) && (my $line = <ZAP>))
{
print
$line;
$numLines+
+;
}

print "here3\n";


That doesn't exit the while loop and it prints the ping output to the
screen.
 
J

Jürgen Exner

[replacing program with better readable formatting]

use warnings;
use strict;
my $cmd = 'ping google.ca|';

open( ZAP, $cmd ) || die "can't fork:$!";

print $cmd ."\n";
print "here2\n";
my $numLines = 0;

while (($numLines < 10) && (my $line = <ZAP>)){
print $line;
$numLines++;
}
print "here3\n";
That doesn't exit the while loop and it prints the ping output to the
screen.

Can't repro your problem. It does stop for me. And if I replace the 10
with a lower number, e.g. 4, it will stop even in the middle of the ping
reports.

jue
 
B

bjlockie

[replacing program with better readable formatting]

use warnings;
use strict;
my $cmd = 'ping google.ca|';

open( ZAP, $cmd ) || die "can't fork:$!";

print $cmd ."\n";
print "here2\n";
my $numLines = 0;

while (($numLines < 10) && (my $line = <ZAP>)){
    print $line;
    $numLines++;}

print "here3\n";
That doesn't exit the while loop and it prints the ping output to the
screen.

Can't repro your problem. It does stop for me. And if I replace the 10
with a lower number, e.g. 4, it will stop even in the middle of the ping
reports.

jue

I was just going to update my post saying it works now. :)
 
B

bjlockie

[replacing program with better readable formatting]

use warnings;
use strict;
my $cmd = 'ping google.ca|';

open( ZAP, $cmd ) || die "can't fork:$!";

print $cmd ."\n";
print "here2\n";
my $numLines = 0;

while (($numLines < 10) && (my $line = <ZAP>)){
    print $line;
    $numLines++;}

print "here3\n";
That doesn't exit the while loop and it prints the ping output to the
screen.

Can't repro your problem. It does stop for me. And if I replace the 10
with a lower number, e.g. 4, it will stop even in the middle of the ping
reports.

jue

Thanks for the help.
 
J

John W. Krahn

bjlockie said:
my $cmd = 'ping google.ca |';

open( ZAP, $cmd ) || die "can't fork: $!";

print $cmd . "\n";

print "here2\n";

my $numLines = 0;

while (($numLines< 10)&& (my $line =<ZAP>)) {
print $line;
$numLines++;
}

print "here3\n";


That doesn't exit the while loop and it prints the ping output to the
screen.

Don't do it like that. You are not testing whether the value returned
from readline is defined. A better way would be:


my @cmd = qw/ ping google.ca /;

open my $ZAP, '-|', @cmd or die "Cannot open pipe from '@cmd' because: $!";

print "@cmd\n";

print "here2\n";

while ( my $line = <$ZAP> ) {
last if $. == 10;
print $line;
}

close $ZAP or warn $! ? "Error closing '@cmd' pipe: $!"
: "Exit status $? from '@cmd'";

print "here3\n";

__END__



John
 
D

dihedral88888

I am wondering if the compression zlib in python could be upgraded to the iterable input and output for different compression algorithm experiments that will outperform the speed of pipelines for all i/o of big chunks.

This is my suggestion. Maybe this is good for talented young to try to gain insights in python modules by just improving an existed one.
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top