1) read a pipe and read parameters at the same time

Paramters of the command line are accessible through the @ARGV array.
Piped input is read from the filehandle STDIN via the "diamond operator" <> or readline. The empty diamond operator is special, since it treats any arguments on the command line as input files, which are attempted to be read before STDIN. (update: If the program is invoked from the terminal and there is no pipe connected to STDIN of the invoked process, its STDIN is connected to the terminal. You can close that STDIN by sending an end-of-file char via the terminal's line discipline, usually typing <Ctrl>-D)

If you want read from STDIN only, use <STDIN> like so:

#!/usr/bin/perl my $Pipe= ""; while (<STDIN>){ $Pipe .= $_; } print "This was read from the pipe:\n"; print "<$Pipe>\n\n"; print "This was the read from the parameters:\n"; print "<@ARGV>\n";

which invoking $ ( echo Hi; sleep 3; echo Bye ) | ./ReadAPipe.pl 1 2 3 4 produces

This was read from the pipe: <Hi Bye > This was the read from the parameters: <1 2 3 4>
2) not hang if the pipe is empty

Except for buffering by the OS, pipes are always empty - this is how pipes work. Writing to a pipe blocks the writer, as long as the reader doesn't read. Reading from the pipe blocks the reader, as long as the writer doesn't write. If the writer closes the pipe, the reader gets end-of-file (eof).
Thus, an empty pipe in your sense would be a pipe which is opened and closed by the writer without having written anything to it.

If you want the reader to time out, you might set up an alarm handler

#!/usr/bin/perl $SIG{ALRM} = sub { warn "waited too long, exiting. This is what I have:\n"; report(); exit; }; alarm(2); # time out after two seconds my $Pipe= ""; while (<STDIN>){ $Pipe .= $_; } report(); sub report { print "This was read from the pipe:\n"; print "<$Pipe>\n\n"; print "This was the read from the parameters:\n"; print "<@ARGV>\n"; }
waited too long, exiting. This is what I have: This was read from the pipe: <Hi > This was the read from the parameters: <1 2 3 4>

- note that the Bye line is missing due to timeout - or you could use select or IO::Select which provides a nice interface to select.

perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

In reply to Re: Need pipe and parameter help by shmem
in thread Need pipe and parameter help by Todd Chester

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.