Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

detect input available from command line

by mifflin (Curate)
on Mar 10, 2011 at 21:28 UTC ( [id://892539]=perlquestion: print w/replies, xml ) Need Help??

mifflin has asked for the wisdom of the Perl Monks concerning the following question:

I have a program that may try to get data from the command line using
while (<>) { }
However, there may not be any input. How do I detect if there is any input so the read will not block? Something like...
if (data is available then) { while (<>) { } } else { # do something else }
UPDATE:

Here is what I ended up doing get the behavior I was looking for...

my $stdin = IO::Select->new(\*STDIN); open my $fh, '|-', $cmd or die $!; if (@ARGV || $stdin->can_read(0)) { while (<>) { print {$fh} $_ or die $!; } } else { print {$fh} "\n" or die $!; } close $fh or die $!;
Now, now matter how the user wants to give my prog the data like...
$ echo "text" | myprog
or
$ myprog <<EOT some text EOT
or
$ myprog afile
I get text without blocking.

Replies are listed 'Best First'.
Re: detect input available from command line
by Fletch (Bishop) on Mar 10, 2011 at 22:17 UTC

    Perhaps the -t test or the PBP-blessed IO::Interactive would help?

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: detect input available from command line
by jwkrahn (Abbot) on Mar 10, 2011 at 21:33 UTC
    if ( @ARGV ) { while (<>) { } } else { # do something else }
      What if the input is not coming from @ARGV but from stdin?
      example:
      $ ./testprog -t testing@testing.com -s test5 <<EOT; > stuff > typed > in > here > EOT
      In this case @ARGV is empty but there is still something to read. How would I detect this?

        You could test

        if (@ARGV or !-t STDIN and !eof()) { while (<>) { ...

        (but any non-input file arguments would need to be removed from @ARGV first, of course)

        This should work with input file arguments on the command line, heredoc input (<<), input redirect (<), and piping into the program (|).

        Update: actually, I think you don't even need the eof().

        I have a program that may try to get data from the command line using

        What if the input is not coming from @ARGV but from stdin?

        If the input is coming from STDIN then it is not on the command line.

Re: detect input available from command line
by BioLion (Curate) on Mar 11, 2011 at 09:58 UTC

    I think OP needs to clarify whether he wants to prompt for input e.g prompt function or take arguments from the command line e.g. @ARGV or getopt::long...

    Hope this helps!

    Just a something something...
      I want to know when
      while (<>) { }
      has something available to read. I'd like to not execute this code when there isn't something available because it will block.

      This idiom will read when @ARGV is populated or when there is some data available to read on STDIN.

      I can handle detecting whether @ARGV has data. What I'm not sure on is how to detect whether STDIN has something available to read. Still testing but I'm not convinced, yet, that -t, as suggested by others, will work here.

        One thing you can do is start a second thread. Let that thread do the blocking read, and pass results to the main thread as they become available.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://892539]
Approved by broomduster
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-03-29 06:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found