To get input from either STDIN or a file, use a variable to store the file handle, rather than using FH or STDIN directly. That way you can use the exact same code to handle both cases - reading from STDIN and reading from a file.

Additionally, I would stay away from slurping, i.e. reading everything into an array at once: @hosts = <STDIN>. It doesn't scale well and even for small data sets, it doesn't give you much opportunity to clean up the data before you put it in the @host array. For example, you might want to get rid of blank lines or trailing new lines.

use strict; use warnings; # set input file handle my $fh; if (scalar(@ARGV)) { # Note: 3 parameter open - this is much safer. my $file = $ARGV[0]; open($fh, '<', $file) or die "Failed to open file $file: $!\n"; } else { $fh = \*STDIN; } # read in the data my @hosts; while (my $line=<$fh>) { # get rid of trailing new line on each hosts name chomp $line; # skip blank lines next unless $line; # add host to list of hosts push @hosts, $line; } # print it results if (scalar(@hosts)) { # we have input so print it out local $"='|'; print "hosts found: |@hosts|\n"; } else { # if @hosts is empty it isn't exactly a syntax error. Users will # be confused if you *only* print out the usage statement. if (scalar(@ARGV)) { # we read from a file but it was empty printf STDERR "file $ARGV[0] was empty!\n"; } else { # oops no input! and we read from STDIN printf STDERR "I expected input from STDIN and got nothing!\n"; } die <<__USAGE__; usage: do_something [file] ... __USAGE__ }

To play with this script and see how it handles STDIN you can either run it by piping data ( echo -e "a\nb\nc\n" | perl MyScript.pm ) or by just running perl MyScript.pm). If you do it the second way, you must stop entering input using Ctrl-D on Linux. If you use Ctrl-C (like I sometimes do), the script will abort before it ever prints out the list of hosts at the end.

Best, beth

Update: Forgot to include usage statement for case when there is no data - added.

Update 2: Changed error message to clarify nature of the problem.


In reply to Re: Nicest way of getting STDIN a beauty contest by ELISHEVA
in thread Nicest way of getting STDIN a beauty contest by mickep76

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.