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

Testing for the existence of STDIN?

by darkomen (Acolyte)
on Jan 24, 2002 at 02:46 UTC ( [id://141049]=perlquestion: print w/replies, xml ) Need Help??

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

I want to write some perl code that can detirmine when it has something in STDIN to process.

Ex: echo a | test.pl

That should process STDIN...

Ex: ./test.pl

That should exit without wanting a character entered into STDIN. Whenever you try and read from STDIN, if it is empty, it waits til it has something in it and gets an EOF... I want to basically be able to test.... Is there something in STDIN? Yes - process the contents of STDIN... No - Skip processing STDIN and exit....

Am I being clear at all? Thanks for any advice...

Replies are listed 'Best First'.
Re: Testing for the existence of STDIN?
by wog (Curate) on Jan 24, 2002 at 03:22 UTC
    In addition to the code above, you could use the -t filetest operator to check if STDIN was opened to a terminal (and thus not a pipe, etc):

    if (-t STDIN) { # we're running from a shell, without input being # piped to us. } else { # ... }
    Or you could also try a non-blocking read of STDIN, which most directly answers your original question of seeing if there is any input waiting without blocking:
    use IO::Handle; STDIN->blocking(0); # and try to read from it, like you would normally. my $line = <STDIN>; if (defined $line) { # we have input, read succeeded } else { # no input at the moment. }
    (Note that this technique may give false negatives if pipes take some time to start writing data.)

Re: Testing for the existence of STDIN?
by Zaxo (Archbishop) on Jan 24, 2002 at 03:28 UTC

    Four argument select 1, undef, undef, $timeout is what you're after.

    After Compline,
    Zaxo

(jeffa) Re: Testing for the existence of STDIN?
by jeffa (Bishop) on Jan 24, 2002 at 02:58 UTC
    This is expected behaviour. If you ask for something, Perl waits until it gets it. Your alternative is to pass arguments to the script, like the name of a file to open. If the file is empty, then you could exit cleanly.

    UPDATE:
    Actually, you _could_ use a time out with $SIG{ALRM}:

    $SIG{ALRM} = sub { die 'STDIN' }; eval { alarm(1); print while <>; alarm(0); }; print "no STDIN\n" if $@ =~ /STDIN/;
    You cannot get finer grained than one second with this way, but you can with select.

    Or .... just use wog's much more elegant solution. wog++

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      I have a piece of working code using sigalrm, i was just hoping there was more of a clean way to do so... It would be nice if you could use the -s test operator on STDIN...

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (4)
As of 2024-03-19 05:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found