in reply to Need pipe and parameter help

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'