Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
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 about the Monastery: (3)
As of 2024-04-25 22:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found