Reputation: 2675
I am trying to use Getopt::Long add command line arguments to my script (seen below). The problem I am running into is related to multiple commands that do different things. For example I have an option flag that sets the configuration file to use with the script the option is -c [config_path]
and I also have -h
for help.
The problem I am running into is I need to have a condition that states whether or not the config option has been used AND a config file has been specified. I tried counting the options in @ARGV
but found if -h
and -c
are specifed it causes the script to move on the to the subroutine load_config
anyway. Because as seen in the code below when 2 arguments are found in @ARGV
it fires the subroutine.
In what way could I fix this? At least in my head specifying -h
and -c
at the same time sorta contradicts each other. Is there a way to make it so only "informational commands" like help cannot be executed with "operational commands" like -c
? Heck is there a way where I get a list of the commands that have been passed? I tried printing the contents of @ARGV
but nothing was in it even though I had specified command arguments.
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Term::ANSIColor;
use XML::Simple;
use Net::Ping;
use Net::OpenSSH;
use Data::Dumper;
# Create a new hash to copy XML::Simple configuration file data into
my %config_file;
# Clear the screen and diplay version information
system ("clear");
print "Solignis's Backup script v0.8 for ESX\\ESX(i) 4.0+\n";
print "Type -h or --help for options\n\n";
# Create a new XML::Simple object
my $xml_obj = XML::Simple->new();
# Create a new Net::Ping object
my $ping_obj = Net::Ping->new();
my $config_file;
my $argcnt = $#ARGV + 1;
GetOptions('h|help' => \&help,
'c|config=s' => \$config_file
);
if ($argcnt == 0) {
print "You must supply a config to be used\n";
} elsif ($argcnt == 2) {
if (! -e $config_file) {
print color 'red';
print "Configuration file not found!\n";
print color 'reset';
print "\n";
die "Script Halted\n";
} else {
load_config();
}
}
sub load_config {
print color 'green';
print "$config_file loaded\n";
print color 'reset';
my $xml_file = $xml_obj->XMLin("$config_file",
SuppressEmpty => 1);
foreach my $key (keys %$xml_file) {
$config_file{$key} = $xml_file->{$key};
}
print Dumper (\%config_file);
}
sub help {
print "Usage: backup.pl -c [config file]\n";
}
Upvotes: 2
Views: 2268
Reputation: 94794
@ARGV is altered by GetOptions, that is why it seems empty. Rather than counting arguments, just directly check if $config_file
is defined.
BTW, IMO there is no need to try to exclude -c
from being used with -h
. Normally a "help" just prints the help text and exits without taking any other action, check that first and it shouldn't matter whether -c
is supplied or not.
Upvotes: 8
Reputation: 1343
You can always set a default value for the options eg my $help = 0; my $config_file = "";
and then test for those values.
Upvotes: 0
Reputation: 601
You might also want to check out Getopt::Euclid which presents some expanded ways to provide options and a cool way of using the programs documentation as the spec for the command-line arguments.
Upvotes: 0
Reputation: 4329
Something like
my $help;
my $config_file;
GetOptions('h|help' => \$help,
'c|config=s' => \$config_file
);
if ( defined $help ) {
help();
} elsif ( defined $config_file ) {
...;
} else {
die "No arguments!";
}
Upvotes: 3