Inspired by this U&L Q&A titled: "https://unix.stackexchange.com/questions/171150/back-to-back-pipes-into-a-command". How could one parse both input via STDIN and via command line arguments to a Perl script?
For example I'd like a script that can consume input parameters from both STDIN and via command line arguments:
$ command | my_command.pl arg1 arg2
And the output of command
would be
arg3
arg4
...
So while my_command.pl
is running, it would be aware of the parameters arg1, arg2, arg3, and arg4.
I came up with the following Perl script which reads data from either STDIN or command line arguments, or both.
$ cat command.pl
#!/usr/bin/perl -w
use strict;
if ( -t STDIN and not @ARGV ) {
print "\n" ."USAGE" . "\n";
print "=====" . "\n";
print "#1:\t $0 <arg1>..<argN>\n";
print "#2:\t <commands> | $0\n";
print "#3:\t <commands> | $0 <arg1>..<argN>\n\n";
exit 1;
}
if ( not -t STDIN ) {
print "\n" . "STDIN ARGS" . "\n";
print "==========" . "\n";
print while (<STDIN>);
print "\n";
}
if (@ARGV) {
print "\n" . "ARGV ARGS" . "\n";
print "=========" . "\n";
foreach (@ARGV) {
print "$_\n";
}
print "\n";
}
The script makes use of both @ARGV
and <STDIN>
, keying off of whether they're defined or not. If neither is defined then it shows usage and bails out.
To test it I put together this secondary script called tests.bash
which runs the above script using a variety of ways to pass input into it. NOTE: That the tests are labelled T00 through T10.
$ cat tests.bash
#!/bin/bash
echo ""
echo ""
echo "====================================="
echo "T00: no input"
./command.pl
echo "====================================="
echo ""
# http://www.tldp.org/LDP/abs/html/subshells.html
echo "====================================="
echo "T01: 2 args w/ pipe via cmd list '(..) | ...' aka. subshell"
( echo "pipearg1"; echo "pipearg2"; ) | ./command.pl
echo "====================================="
echo ""
# http://www.tldp.org/LDP/abs/html/special-chars.html#CODEBLOCKREF
echo "====================================="
echo "T02: 2 args w/ pipe via inline group '{..} | ...' aka. code block"
{ echo "pipearg1"; echo "pipearg2"; } | ./command.pl
echo "====================================="
echo ""
echo "====================================="
echo "T03: 2 cli args 'cmd A1 A2'"
./command.pl argv1 argv2
echo "====================================="
echo ""
echo "====================================="
echo "T04: T01 + T03"
( echo "pipearg1"; echo "pipearg2"; ) | ./command.pl argv1 argv2
echo "====================================="
echo ""
echo "====================================="
echo "T05: T02 + T03"
{ echo "pipearg1"; echo "pipearg2"; } | ./command.pl argv1 argv2
echo "====================================="
echo ""
echo "====================================="
echo "T06: echo with newline: $'..\n..'"
echo $'pipearg1\npipearg2' | ./command.pl
echo "====================================="
echo ""
echo "====================================="
echo "T07: echo -e with newline: '..\n..'"
echo -e "pipearg1\npipearg2" | ./command.pl
echo "====================================="
echo ""
echo "====================================="
echo "T08: 2 cli args via HEREDOC 'cmd <<EOF ... EOF'"
./command.pl <<EOF
arghd1
arghd2
EOF
echo "====================================="
echo ""
echo "====================================="
echo "T09: 2 cli args via process substitution 'cmd < <(...cmds...)'"
./command.pl < <(echo argps1; echo argps2)
echo "====================================="
echo ""
echo "====================================="
echo "T10: T03 + T09"
./command.pl argv1 argv2 < <(echo argps1; echo argps2)
echo "====================================="
echo ""
The tests.bash
script is designed to run 11 different tests, ranging from using HEREDOCS, to subshells, to passing command line arguments. It also uses these in combinations to fully test the Perl script, command.pl
.
$ ./tests.bash
=====================================
T00: no input
USAGE
=====
#1: ./command.pl <arg1>..<argN>
#2: <commands> | ./command.pl
#3: <commands> | ./command.pl <arg1>..<argN>
=====================================
=====================================
T01: 2 args w/ pipe via cmd list '(..) | ...' aka. subshell
STDIN ARGS
==========
pipearg1
pipearg2
=====================================
=====================================
T02: 2 args w/ pipe via inline group '{..} | ...' aka. code block
STDIN ARGS
==========
pipearg1
pipearg2
=====================================
=====================================
T03: 2 cli args 'cmd A1 A2'
ARGV ARGS
=========
argv1
argv2
=====================================
=====================================
T04: T01 + T03
STDIN ARGS
==========
pipearg1
pipearg2
ARGV ARGS
=========
argv1
argv2
=====================================
=====================================
T05: T02 + T03
STDIN ARGS
==========
pipearg1
pipearg2
ARGV ARGS
=========
argv1
argv2
=====================================
=====================================
T06: echo with newline: $'..\n..'
STDIN ARGS
==========
pipearg1
pipearg2
=====================================
=====================================
T07: echo -e with newline: '..\n..'
STDIN ARGS
==========
pipearg1
pipearg2
=====================================
=====================================
T08: 2 cli args via HEREDOC 'cmd <<EOF ... EOF'
STDIN ARGS
==========
arghd1
arghd2
=====================================
=====================================
T09: 2 cli args via process substitution 'cmd < <(...cmds...)'
STDIN ARGS
==========
argps1
argps2
=====================================
=====================================
T10: T03 + T09
STDIN ARGS
==========
argps1
argps2
ARGV ARGS
=========
argv1
argv2
=====================================
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