Command line arguments
Known number of arguments
#!/usr/bin/perl
use strict;
use warnings;
if($#ARGV != 1)
{
print STDERR "Please provide exactly two numbers as command line arguments\nExiting program\n";
# usual convention to use exit values is '0' for success and '1' for error
exit(1);
}
else
{
my ($num1, $num2) = @ARGV;
my $sum = $num1 + $num2;
print "$num1 + $num2 = $sum\n";
}
- Command line arguments given to Perl program are automatically saved in
@ARGV
array - It is a good idea to let the user know something went wrong
- Use of
exit(1)
is helpful if the program is used by another program which can then use theexit
value to take decision - As the program terminates with error message for wrong usage, use
STDERR
filehandle instead of defaultSTDOUT
- As can be seen from sample output below, giving string as input for numeric addition only results in a warning. If you want to escalate this to an error, modify warnings to
use warnings FATAL => qw(numeric);
This will cause the program to exit andecho $?
yielding value of255
- more on different usage of warnings
$ ./sum_of_two_numbers.pl 2.34 '56'
2.34 + 56 = 58.34
$ echo $?
0
$ ./sum_of_two_numbers.pl 3 2 5
Please provide exactly two numbers as command line arguments
Exiting program
$ echo $?
1
$ ./sum_of_two_numbers.pl 3 a
Argument "a" isn't numeric in addition (+) at ./sum_of_two_numbers.pl line 14.
3 + a = 3
$ echo $?
0
Varying number of arguments
#!/usr/bin/perl
use strict;
use warnings;
if($#ARGV < 0)
{
print STDERR "Please provide atleast one filename as command line argument\nExiting program\n";
exit(1);
}
else
{
foreach (@ARGV)
{
# -f option checks if the argument is a plain file
if( !(-f $_) )
{
print "File '$_' not found\n";
next;
}
my $line_count = `wc -l < $_`;
chomp($line_count);
printf "%-30s: %-4d lines\n", $_, $line_count;
}
}
- When dealing with filenames obtained as user input, it is good to do a sanity check before processing
- As seen earlier, output of external command execution contains trailing newline character, which might need to be taken care
- Note that Perl automatically substitutes value of
$_
before calling external command, use\
to escape special characters when needed
$ ./varying_command_line_args.pl *pl
arrays.pl : 59 lines
backticks.pl : 7 lines
bitwise.pl : 13 lines
file_reading_error.pl : 19 lines
file_reading.pl : 15 lines
...
The $0 argument
#!/usr/bin/perl
use strict;
use warnings;
if($#ARGV != 0)
{
print STDERR "Please provide exactly one filename as command line argument\nExiting program\n";
exit(1);
}
else
{
my $filename = $ARGV[0];
unless(-f $filename)
{
print STDERR "File '$filename' not found\nExiting program\n";
exit(1);
}
# $0 special variable contains the name of program being executed
if($0 =~ m/line_count.pl/)
{
print "No. of lines in '$filename' is: ".`wc -l < $filename`;
}
if($0 =~ m/word_count.pl/)
{
print "No. of words in '$filename' is: ".`wc -w < $filename`;
}
}
- Using the
$0
special variable, same program can be repurposed for different functionalities unless
helps in situation where you need to check a negated test condition. In this case,unless(-f $filename)
is equivalent toif( !(-f $filename) )
$ ./line_count.pl arrays.pl
No. of lines in 'arrays.pl' is: 59
$ ln -s line_count.pl word_count.pl
$ ./word_count.pl arrays.pl
No. of words in 'arrays.pl' is: 247
$ wc -lw arrays.pl
59 247 arrays.pl
Command line switches
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
our ($opt_h, $opt_f);
getopts('hf:');
if($opt_h)
{
print "----------------------------------------------------------------\n";
print "This program sorts a given file and removes any duplicate lines\n\n";
print "Usage:\n";
print "./getopt_std.pl -h \t\tDisplays this help\n";
print "./getopt_std.pl -f filename \tfile to be sorted uniquely\n";
print "----------------------------------------------------------------\n";
}
elsif($opt_f)
{
# no need file test if default behavior of command serves the purpose
my $cmd_exit_value = system("sort -u $opt_f -o $opt_f");
print "$opt_f is now uniquely sorted\n" unless($cmd_exit_value);
}
else
{
print "Oops! Something went wrong\nUse './getopt_std.pl -h' to get help\n";
}
Getopt
is an easy way to build command-line like functionality for your Perl program- To indicate that you need argument along with option, append colon to the option, like
f:
- For just option without argument, use the letter you want, like
h
- Because of
use strict;
construct, we need to declare the$opt_
variables by adding the option letters as suffix. Perl then automatically populates these variables based on user input - The
$opt_
variables have the initial valueundef
.$opt_h
gets assigned to1
if-h
option is given by user and$opt_f
to filename in case of-f
$ ./getopt_std.pl -h
----------------------------------------------------------------
This program sorts a given file and removes any duplicate lines
Usage:
./getopt_std.pl -h Displays this help
./getopt_std.pl -f filename file to be sorted uniquely
----------------------------------------------------------------
$ cat test_list.txt
basic_test
input_test
async_test
output_test
input_test
sync_test
$ ./getopt_std.pl -f test_list.txt
test_list.txt is now uniquely sorted
$ cat test_list.txt
async_test
basic_test
input_test
output_test
sync_test
$ ./getopt_std.pl -x
Unknown option: x
Oops! Something went wrong
Use './getopt_std.pl -h' to get help
$ ./getopt_std.pl -f non_existing_file.txt
sort: cannot read: non_existing_file.txt: No such file or directory
Further Reading