This question was necessitated out of laziness on my part, because I have dozens of scripts that are executed in the simple structure:
perl my_script.pl my_input_file
...and the output is printed to stdout. However, now I realize that I have certain situation in which I would like to pipe input into these scripts. So, something like this:
perl my_script.pl my_input_file | perl my_next_script.pl | perl third_script.pl > output
Does anyone know of a way to do this without recoding all of my scripts to accept stdin instead of a user-defined input file? My scripts look for the filename by a statement like this:
open(INPUT,$ARGV[0]) || die("Can't open the input file");
Thanks for any suggestions!
Perl's open function opens a pipe instead of a file when you append or prepend a pipe symbol to the second argument to open . This turns the rest of the arguments into a command, which will be interpreted as a process (or set of processes) that you want to pipe a stream of data either into or out of.
STDIN in Perl is used to take input from the keyboard unless its work has been redefined by the user. In order to take input from the keyboard or operator is used in Perl. This operator reads a line entered through the keyboard along with the newline character corresponding to the ENTER we press after input.
Simple piping uses | character to send the STDOUT from one application to the STDIN of the next application. One nice thing about piping in Linux is that each application that is executed is run in parallel, so each application is processing its STDIN and sending its STDOUT as soon as it is received.
Use -
as filename
perl my_script.pl my_input_file | perl my_next_script.pl - | perl third_script.pl - > output
mpapec has provided the simplest solution. I would like to recommend the diamond operator: <>
.
In a script where you would do
open my $fh, "<", $ARGV[0] or die $!;
while (<$fh>) {
...
You can use the diamond operator to replace most of that code
while (<>) {
...
The file handle name will be ARGV
if you use argument file names, or STDIN
if not. The file name will be found in $ARGV
.
This operator invokes a behaviour where Perl looks for input either from file name arguments, or from standard input.
Which means that whether you do
inputpipe | script.pl
or
script.pl inputfile.txt
The diamond operator will take the input just fine.
Note: Your open
statement is dangerous. You should use three argument open with explicit mode, and lexical file handle. The die
statement connected to it should contain the error variable $!
to provide information about why the open failed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With