How do I detect if I have incoming data in <STDIN> when I pipe somethingto my perl script ?

A

Andreas Berg

Greetings,

I'm writing a script that is supposed to fetch information from said:
cat file.txt | myscript.pl

With this, I will get what I want into <STDIN> and I can read it. But,
this is the only case I want to read it. I do not want my script to try
to read from a file in case I do have any command line paramters and I
do not want the script to wait for keyboard input. If something is piped
to the script, I want that data, if nothing is piped to the script, I
dont want it to do anything with <STDIN>, how do I accomplish this ?

regards,
Andreas
 
S

Sandman

Andreas Berg said:
Greetings,



With this, I will get what I want into <STDIN> and I can read it. But,
this is the only case I want to read it. I do not want my script to try
to read from a file in case I do have any command line paramters and I
do not want the script to wait for keyboard input. If something is piped
to the script, I want that data, if nothing is piped to the script, I
dont want it to do anything with <STDIN>, how do I accomplish this ?

regards,
Andreas

cat file.txt | myscript.pl -stdin


And have myscript.pl read from <STDIN> only if $ARGV[0] is "-stdin", or use
getopts if you want more elaborate control of the parameters. This is, if I am
reading this line correctly:

"I do not want my script to try to read from a file in case I do
have any command line paramters"

I take that one as if you don't want to call your script with

myscript.pl -f file.txt

to read the file, and not to mean that you don't want to use parameters at all.
 
A

Andreas Berg

The script will have command line parameters for other things and when I
do not pipe something to the script, I dont want it to try to read these
command line parameters as if they where a file.

And, I never want the script to read from keyboard.

Having -stdin as a command line parameter would work, but it is a dirty
solution in my opinion. Doesn't look very nice.

regards,
Andreas
Greetings,



With this, I will get what I want into <STDIN> and I can read it. But,
this is the only case I want to read it. I do not want my script to try
to read from a file in case I do have any command line paramters and I
do not want the script to wait for keyboard input. If something is piped
to the script, I want that data, if nothing is piped to the script, I
dont want it to do anything with <STDIN>, how do I accomplish this ?

regards,
Andreas


cat file.txt | myscript.pl -stdin


And have myscript.pl read from <STDIN> only if $ARGV[0] is "-stdin", or use
getopts if you want more elaborate control of the parameters. This is, if I am
reading this line correctly:

"I do not want my script to try to read from a file in case I do
have any command line paramters"

I take that one as if you don't want to call your script with

myscript.pl -f file.txt

to read the file, and not to mean that you don't want to use parameters at all.
 
G

Gunnar Hjalmarsson

Andreas said:
I'm writing a script that is supposed to fetch information from


With this, I will get what I want into <STDIN> and I can read it.
But, this is the only case I want to read it. I do not want my
script to try to read from a file in case I do have any command
line paramters and I do not want the script to wait for keyboard
input. If something is piped to the script, I want that data, if
nothing is piped to the script, I dont want it to do anything with
<STDIN>, how do I accomplish this ?

unless (eof STDIN) {
my $data = do { local $/; <STDIN> };
# process data
}
 
R

Richard Gration

The script will have command line parameters for other things and when I
do not pipe something to the script, I dont want it to try to read these
command line parameters as if they where a file.

This will never happen, for exactly the reason you don't want it to
happen - they are two entirely different things. CLI parameters appear in
@ARGV, stdin appears on <STDIN>.
 
C

ctcgag

Gunnar Hjalmarsson said:
unless (eof STDIN) {
my $data = do { local $/; <STDIN> };
# process data
}

On my computer, 'eof STDIN' will, when run without STDIN redirection, block
and wait for one line of user input on STDIN, so it doesn't do what the OP
wants.

In my hands, the file test "-p STDIN" works:

$ perl -le 'print -p STDIN ? "Read STDIN" : "Dont read STDIN";'
Dont read STDIN
$ echo blah | perl -le 'print -p STDIN ? "Read STDIN" : "Dont read STDIN";'
Read STDIN


Xho
 
G

Gunnar Hjalmarsson

On my computer, 'eof STDIN' will, when run without STDIN
redirection, block and wait for one line of user input on STDIN, so
it doesn't do what the OP wants.

Hmm... So it seems.

I tested the code in a CGI context, calling the script with or without
POSTing data, and then it worked. Thought it would work from command
line as well. Obviously not. :(

Thanks!
 
A

Andreas Berg

Richard said:
This will never happen, for exactly the reason you don't want it to
happen - they are two entirely different things. CLI parameters appear in
@ARGV, stdin appears on <STDIN>.

Actually, if the first command line parameter is a file, you can read it
using <STDIN>, or maybe its just <> you can read it with, but if I
recall correctly, they are the same thing.

regards,
Andreas
 
R

Richard Gration

"Andreas Berg" said:
Actually, if the first command line parameter is a file, you can read it
using <STDIN>, or maybe its just <> you can read it with, but if I
recall correctly, they are the same thing.

Right second time. The <> is some perl magic which treats the command
line arguments as filenames and allows you to read their content via <>.
This has nothing to do with stdin though, <> and <STDIN> are different
beasts.

#!/usr/bin/perl

print 'Do you want to see the contents of <>? (y/n) ';
chomp (my $ans = <STDIN>);

if ($ans =~ /^y/i) {
print for <>;
} else {
print "Bye bye!";
}

HTH
Rich
 
G

gnari

Richard Gration said:
Right second time. The <> is some perl magic which treats the command
line arguments as filenames and allows you to read their content via <>.
This has nothing to do with stdin though, <> and <STDIN> are different
beasts.

different beasts, but related.
do not forget that in the abscence of filename arguments, <> reads
from STDIN

gnari
 
J

Joe Smith

Andreas said:
I do not want the script to wait for keyboard input.

That's different than what you asked the the subject line.

Q: How can I tell when data becomes available on STDIN?
A: Use select() checking for input available on file handle 0.
This is recommended when reading from a TCP/IP socket.

Q: How can I tell when STDIN is associated with a pipe (or
redirected from an input file) and not coming from the terminal?
A: Use the -t() function.

if (-t) {
print "Input appears to be from a tty; not reading from it\n";
@lines = ();
} else {
print "Reading from input file or pipe\n"
@lines = <STDIN>;
}
print "Read ",scalar(@lines)," lines\n";

-Joe
 
J

Joe Smith

In my hands, the file test "-p STDIN" works:

$ perl -le 'print -p STDIN ? "Read STDIN" : "Dont read STDIN";'
Dont read STDIN
$ echo blah | perl -le 'print -p STDIN ? "Read STDIN" : "Dont read STDIN";'
Read STDIN

That works for input from a pipe, but not when redirecting input from a file.
The file test "-t STDIN" handles both.
-Joe
 

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,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top