Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Using stdin only if there is input on it, but skipping it if there is no data

by mldvx4 (Monk)
on Nov 18, 2020 at 07:41 UTC ( #11123769=perlquestion: print w/replies, xml ) Need Help??

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

I'd like to use stdin for input, but only if there is some data on it. If there is no data, I would like the script to continue and not wait for it.

I have figured out how to get these following methods of invoking the script to read data by adding various methods to the script,

./foo.pl bar01.data ./foo.pl bar01.data bar02.data ./foo.pl < bar01.data ./foo.pl < <(cat bar01.data) cat bar01.data | ./foo.pl

What module or method should I look at to add to the above so that the following does not wait for input but merely continues without any data?

./foo.pl

I hope it is not too complex.

Replies are listed 'Best First'.
Re: Using stdin only if there is input on it, but skipping it if there is no data
by Fletch (Chancellor) on Nov 18, 2020 at 07:48 UTC

    First thing that comes to mind is if @ARGV were empty (you're given no filenames) then check if -t STDIN is true (meaning it's a tty device not a pipe).

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

      Thanks. That seems to allow me to use redirects and does not interfere if there is not.

      . . . } elsif ($#filenames < 0 && ! -t STDIN) { unshift(@filenames, '/dev/stdin') } . . .

      It is done at the end of all the checking of sources, right before the data gets read.

Re: Using stdin only if there is input on it, but skipping it if there is no data
by salva (Abbot) on Nov 18, 2020 at 08:39 UTC
    You can use select (see perlfunc) to check whether data is available from a file descriptor.

    Though, that could incur in a race condition, for instance, when the data is generated by another process running in parallel. So, you should probably set a safe waiting time (the last select argument).

Re: Using stdin only if there is input on it, but skipping it if there is no data
by BillKSmith (Prior) on Nov 18, 2020 at 16:10 UTC
    It seems that Fletch has provided you with a workaround. If you are interested in a more formal solution, you will find that it is probably system dependent. Start by reading getc and Term::Key.

    UPDATE: I found the link to Term::ReadKey in the documentation of getc. It appears to have useful info. Sorry for the error in posting the link.

    Bill

      Thanks. The link for Term::Key seems dead, but Term::TermKey is present. However, the CPAN page says that it is deprecated. Is there any other option for more formal solutions, besides getc?

        I'm not aware of any deprecation of Term::ReadKey so perhaps that might also be an option for you.


        🦛

Re: Using stdin only if there is input on it, but skipping it if there is no data
by perlfan (Vicar) on Nov 18, 2020 at 19:41 UTC
    In the past I have used a combination of a timeout and a black that the user sets to explicitly say, "look for STDIN", sort of like some *nix utilities use the lone "dash" (-) (e.g., tar, etc). Also I found this solution (stackexchange) that is not my solution but demonstrates using a time out with the read.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11123769]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2020-12-03 07:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How often do you use taint mode?





    Results (52 votes). Check out past polls.

    Notices?