Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
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 chilling in the Monastery: (5)
As of 2024-04-24 19:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found