Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Testing <>

by Anonymous Monk
on Oct 03, 2011 at 15:17 UTC ( [id://929359]=perlquestion: print w/replies, xml ) Need Help??

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

Simple problem for you good folks.

I want a script that reads both from stdin and from a any file parameter. In other words a script that can be used as any other unix command line tool.

The problem is that if there's no stdin and no command line args then the script just waits for input.

I want to test to see if there is any input from a pipe or file and if not close with a usage message. How can I test, <>?

Thanks

use strict; use warnings; while (<>) { print; }

Replies are listed 'Best First'.
Re: Testing <>
by Corion (Patriarch) on Oct 03, 2011 at 15:31 UTC

    STDIN is always there.

    Maybe you want to detect instead of whether your script is supposed to get interactive input or input piped from a file, or another program?

    if( -t and !@ARGV) { die "Need a file or stream on standard input"; }; while (<>) { ... };
    >perl -w tmp.pl Need a file or stream on standard input at tmp.pl line 2. >perl -w tmp.pl tmp.pl >perl -w tmp.pl <tmp.pl
      Thanks Corion.

      That's the simple solution I knew had to be there. I didn't know you could use -t in that context. Oh well live and yearn.

      Thanks again

Re: Testing <>
by ikegami (Patriarch) on Oct 03, 2011 at 15:44 UTC

    The problem is that if there's no stdin and no command line args then the script just waits for input.

    Just like cat, perl, sort, etc, etc, etc.

    This is standard behaviour. Why does it matter to you? Both using -t and implementing a command line option that says there is no STDIN have their drawbacks.

      > Just like cat, perl, sort, etc, etc, etc.
      > This is standard behaviour.

      Yeah, I know and I don't like it.

      I still think, as I did 20 years ago when I first started using UNIX, that these sitting commands waiting for user input was pretty pointless.

      I've never felt the urge to type in 'sort' enter some values then excitedly hitting ^D to see the result.

        I never manually type in stuff, but I often copy-and-paste stuff into a program like sort (or a Perl oneliner) to munge data. That would not be possible with your approach.

Re: Testing <>
by kennethk (Abbot) on Oct 03, 2011 at 15:25 UTC
    You can detect the presence of waiting input using select, like:
    use strict; use warnings; my $vector = ''; vec($vector,fileno(STDIN),1) = 1; if (select($vector,undef,undef,0.01)) { while (<>) { print; } }

    where I have set a 10 millisecond timeout. Might be easier and more portable though to simply pass the filename as argument, and open it yourself. Like many other unix command line tools.

      That works for
      /tmp/>echo "hello world\n" | myscript
      and now called on its own doesn't hang
      /tmp/>myscript
      but there again its not clear how a usage message could be printed out.

      But it now fails when passed a filename

      /tmp/>cat x October 2011 S M Tu W Th F S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /tmp/myscript x
      it doesn't print the contents of the file :-( Isn't there a simpler solution? I thought that this would have a simple, forehead slapping, solution.
Re: Testing <>
by Anonymous Monk on Oct 03, 2011 at 15:32 UTC

Log In?
Username:
Password:

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

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

    No recent polls found