unix pipes to perl scripts

T

trt.

Got a problem piping command output to a perl script, in the test below
the loop accepts the piped files but it also interferes with my STDIN!

===test=============================
$ls -1 *.cfg | ./pp
file: hosts.cfg
file: pseries.cfg

type something : you typed :
===test=============================

I do not get the chance to type something in after "type something"...

Do i have to flush some variable inbetween the foreach loop and
<STDIN>?
Is looping trough <ARGV> or <> the best way to catch piped input?

===code=============================
$cat ./pp
#!/usr/bin/perl

while ( <> ) {
print "file: $_";

};

print "\ntype something : ";
$answer = <STDIN>;
print "you typed : $answer \n";
===code=============================

nb: also tried open FH, "-|" ... close FH, no difference.

thanks!
 
J

jl_post

trt. said:
Got a problem piping command output to a perl script,
in the test below the loop accepts the piped files but
it also interferes with my STDIN!

===test=============================
$ls -1 *.cfg | ./pp
file: hosts.cfg
file: pseries.cfg

type something : you typed :
===test=============================

I do not get the chance to type something in after
"type something"...

Do i have to flush some variable inbetween the foreach
loop and <STDIN>?
Is looping trough <ARGV> or <> the best way to catch
piped input?

===code=============================
$cat ./pp
#!/usr/bin/perl

while ( <> ) {
print "file: $_";

};

print "\ntype something : ";
$answer = <STDIN>;
print "you typed : $answer \n";
===code=============================


Try adding the lines:

$| = 1; # autoflush
open(STDIN, "</dev/tty") or die $!;

right before the line that prints "type something". This will make any
subsequent reads from STDIN read from the terminal (and not from the
pipe).

I hope this helps!

-- Jean-Luc
 
T

trt.

I tried using $|=1 but opening the STDIN filehandle for /dev/tty did do
the trick -- nice, thank you!
 
J

Josef Moellers

trt. said:
Got a problem piping command output to a perl script, in the test below
the loop accepts the piped files but it also interferes with my STDIN!

===test=============================
$ls -1 *.cfg | ./pp
file: hosts.cfg
file: pseries.cfg

type something : you typed :
===test=============================

I do not get the chance to type something in after "type something"...

Do i have to flush some variable inbetween the foreach loop and
<STDIN>?
Is looping trough <ARGV> or <> the best way to catch piped input?

The STDIN of your pp script is redirected from the keyboard to the
STDOUT of the ls command. It is not automagically reconnected to the
keyboard once the ls command has terminated.
It would not be a good idea to reconnect to the keyboard, as quite a lot
of scripts depend upon pipelines to perform certain tasks (this is a
design feature of the UN*X/Linux architecture).

If you must read some more input from the keyboard, you can open /dev/tty:

#!/usr/bin/perl

while ( <> ) {
print "file: $_";

};

open STDIN, '<', '/dev/tty'; #################################
print "\ntype something : ";
$answer = <STDIN>;
print "you typed : $answer \n";

Note that you'll get problems with buffering, though.

Josef
 
C

Chris Mattern

trt. said:
Got a problem piping command output to a perl script, in the test below
the loop accepts the piped files but it also interferes with my STDIN!

===test=============================
$ls -1 *.cfg | ./pp
file: hosts.cfg
file: pseries.cfg

type something : you typed :
===test=============================

I do not get the chance to type something in after "type something"...

Well, of course this interferes with your STDIN. You told it to. The
pipeline you set up in the shell command made the output of "ls -l *.cfg"
STDIN for pp, not your terminal. <> reads STDIN if you don't give the perl
script any arguments, which you did not. So it reads STDIN to end of
file (which happens when ls -l *.cfg is finished). Then when you try
to read STDIN again, it's already reached end of file, so it just
returns with no data.
Do i have to flush some variable inbetween the foreach loop and
<STDIN>?
Is looping trough <ARGV> or <> the best way to catch piped input?

===code=============================
$cat ./pp
#!/usr/bin/perl

while ( <> ) {
print "file: $_";

};

print "\ntype something : ";
$answer = <STDIN>;
print "you typed : $answer \n";
===code=============================

nb: also tried open FH, "-|" ... close FH, no difference.

thanks!

--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top