how to pass command line arguments to getopt in perl - perl

I am new to Perl. I have to pass command line arguments to GetOptions method so I can access those variables. I have tried the following code:
use Getopt::Long;
$result = GetOptions($ARGV[0] => \$serv_name, $ARGV[1] => \$serv_id);
print "Server name is $serv_name & server id is $serv_id";
But I am not getting desired output. So how do I do this?

Try this (inspired from documentation of Getopt::Long):
use Getopt::Long;
GetOptions(
"server_id=i" => \my $serv_id, # numeric
"server_name=s" => \my $serv_name, # string
) or die "Error in command line arguments\n";
print "Server name is $serv_name & server id is $serv_id\n";
If server_id argument maybe not numeric, change "server_id=i" to "server_id=s"
And call the program these ways:
%> perl ex.pl --server_name=the_name --server_id=1234
# or
%> perl ex.pl -server_name the_name -server_id 1234

Related

Script does not die if there are incorrect arguments

I'm quite new to the Perl programming. I want to use GetOptions to parse input arguments for my script. I have simple problem - I want script to exit with usage message if there's mess in arguments or arguments are missing values (for mandatory arguments).
src_xml is mandatory argument but if I run the script not providing value for this argument, I get an error message about usage of uninitialized value $src_xml in -e at tenant_tenant.pl. What am I doing wrong? Or do I have to check every variable if its defined?
my $dev;
my $src_xml;
my $tgt_syscd = 'L86';
my $tgt_path = '/tmp/test/exports';
my $help;
GetOptions('src_xml=s' => \$src_xml,
'tgt_syscd=s' => \$tgt_syscd,
'tgt_path=s' => \$tgt_path,
'dev' => \$dev,
'h|help' => \$help
) or die "Usage: perl $0 --src_xml NAME --tgt_syscd NAME --tgt_path NAME
\n";
#checking for help
if ( defined $help ) {
die $help_message;
}
Your script will die only this way:
perl ./foo.pl --src_xml=
Check arguments with custom subroutine?
GetOptions(
'dec-to-base35=i' => \&dec_to_base35,
'base35-to-dec=s' => \&base35_to_dec,
);
sub dec_to_base35 ( $opt_name, $decimal_value ) {
...
Complete example here
BTW, you can join "Perl weekly challenge", this may help to learn something new

How to get the file from the directory using command line arguments using perl?

I tried to fetch the file with folder name(i.e pro) and location(i.e “/c/lol/ap/a/ds/crent/stup/pjects/DEMO/mfile.txt) and run the script(i.e perl readfile.pl) using command line arguments.So i tried for the following sample script by my own.But i feel my script is totally wrong.Could anyone help me the right way to approach.
Sample Script:(perl readfile.pl)
use strict;
use warnings;
use Getopt::Long qw(GetOptions);
my $pro;
my $mfile;
my $odir;
GetOptions('pro' => \$pro) or die "Usage: $0 --pro\n";
GetOptions('mfile' =>\$mfile) or die "Usage:$0 --mfile\n";
GetOptions('odir' =>\$odir) or die "Usage:$0 --odir\n";
print $pro ? 'pro' : 'no pro';
Error:
Unknown option: mfile
Unknown option: odir
Usage: readfile.pl --pro
To run command line as follows :
I should create the script to run the command line as follows.
perl readfile.pl -pro “pr1” -mfile “/c/lol/ap/a/ds/crent/stup/pjects/DEMO/mfile.txt” -odir “/home/html_files”
The call GetOptions('pro' => \$pro) sees all options other than -pro as invalid, so you must process all possible command line options in a single call
Since your options have a string value, you also need to append =s to the option name
It would look like this
use strict;
use warnings 'all';
use Getopt::Long 'GetOptions';
GetOptions(
'pro=s' => \my $pro,
'mfile=s' => \my $mfile,
'odir=s' => \my $odir,
);
print $pro ? "pro = $pro\n" : "no pro\n";
print $mfile ? "mfile = $mfile\n" : "no mfile\n";
print $odir ? "odir = $odir\n" : "no odir\n";
output
pro = pr1
mfile = /c/lol/ap/a/ds/crent/stup/pjects/DEMO/mfile.txt
odir = /home/html_files
Not sure what you're trying to achieve here, but your usage of GetOptions is wrong. If you call it, this tries to process all commandline options, not just one. So everything not defined in your first call to GetOption ends up triggering the or die ... part at the end and stops the program, resulting in the usage message. Please look up PerlDoc for some useful examples.
You also have to use two hyphens for your options in the commandline call to let it work...

How can I pass Getopt::Long options to a subroutine that's also an option?

I am trying to setup Getopt::Long to handle the arguments from a configuration script.
Here is my starter;
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
my $config_file = '';
GetOptions (
'config|c=s' => \$config_file,
'add|a' => \&add_server,
'del|d' => \&del_server,
);
sub add_server {
print "$config_file\n";
}
sub del_server {
# Left blank for now.
}
The odd thing is I am running into a problem when I run my script with something like this,
./config.pl -a -c config.xml
It does NOT print the -c option, but if I run it like this,
./config.pl -c config.xml -a
it works like it should.
I think I understand the reason why, it has to do with the order execution right?
The question is how can I fix it? Should I use Getopt::Long in conjunction with #ARGV?
Ultimatly I am trying to make the command line args pass into the subroutine that I am calling. So if -a or --add I want the options of -c or --config to pass into the subroutine when it is called.
Any ideas?
I don't see the need to call the subroutine directly from the GetOptions call. Control the order like this:
use strict;
use warnings;
use Getopt::Long;
my %opts = (config => '');
GetOptions(\%opts, qw(
config|c=s
add|a
del|d
));
add_server() if $opts{add};
del_server() if $opts{del};
sub add_server {
print "$opts{config}\n";
}
sub del_server {}
Boiling the example down a little bit...
use strict;
use warnings;
use Getopt::Long;
my $config_file = '';
GetOptions (
'config|c=s' => \$config_file,
'add|a' => sub{add_server($config_file);}
);
sub add_server
{
my $config=shift;
if(defined($config))
{
print "Got this for a config file: $config\n";
}
else
{
print "No argument supplied to add_server\n";
}
}
... and running config.pl -c blurg -a returns the output Got this for a config file: blurg, and running config.pl -a -c blurg returns Got this for a config file:.
So, what I suspect is happening is that the options are assigned in the order given. So in the first case $config_file is assigned to the -c argument and then the add_server subroutine is called (with the correct argument), whereas in the second case, add_server is immediately fired off with no argument and then $config_file is assigned.
All this aside, I'd recommend making -a a boolean and do whatever you want to do if it's enabled (and if an argument for -c is supplied).
The callbacks are called as the options are encountered, so add_server is being called before -c has been encountered when you do
./config.pl -a -c config.xml
Based on the latest info, you now want:
use Getopt::Long qw( GetOptions );
GetOptions(
'a=s' => \my $opt_a,
'd=s' => \my $opt_d,
'h=s' => \my $opt_h,
'p=s' => \my $opt_p,
) or usage();
GetOptions(
'arg=s' => sub { print "$_[1]\n"; },
);
Enable the pass_through option on Getopt::Long so that it will ignore unknown options, then call GetOptions once for your options, disable it again, and then use GetOptions again for your command.

debugging perl script - variable interpolation

Try to debug this script. I think it maybe an issue of variable interpolation? I'm not sure.
It works using options if I pass the values like so:
perl test-file-exists.pl --file /proj/Output/20111126/_GOOD
I am trying to remove the option of passing in --file since I need to generate the date
dynamically.
perl test-file-exists.pl
Given the code changes below (I commented out the options piece). I am trying to create the string (see $chkfil). I am getting errors passing in $dt4. Somehow, its not passing in the file string that I am creating into this other module.
use strict;
use warnings;
use lib '/home/test/lib';
use ProxyCmd;
use Getopt::Long;
#
### Set up for Getopt
#
#my $chkfil;
#my $help;
#usage() if ( #ARGV < 1 or
# ! GetOptions('help|?' => \$help,
# 'file=s' => \$chkfil)
# or defined $help );
my $cmd = ProxyCmd->new( User=>"test_acct",
AuthToken=>"YToken",
loginServer=>"host.com");
# Get previous day
my $dt4 = qx {date --date='-1day' +'%Y%m%d'};
# Check file
my $chkfil = qq{/proj/Output/$dt4/_GOOD};
# Now test the fileExists function
print "Checking 'fileExists':\n";
my $feResults = $cmd->fileExists("$chkfil");
if ($feResults == 0) {
print "File Exists!\n";
} else {
print "File Does Not Exist\n";
}
sub usage
{
print "Unknown option: #_\n" if ( #_ );
print "usage: program [--file /proj/Output/20111126/_GOOD] [--help|-?]\n";
exit;
}
When you use backticks or qx, you get the trailing newline included so chomp it off:
my $dt4 = qx {date --date='-1day' +'%Y%m%d'};
chomp $dt4;
and you'll get a sensible filename.
You could also use DateTime and friends to avoid shelling out entirely.

How to use GetOptions utility to handle 'optional' command-line arguments in Perl?

There are many Perl tutorials explaining how to use GetOptions utility to process only the command-line arguments which are expected, else exit with an appropriate message.
In my requirement I have following optional command-line arguments, like,
-z zip_dir_path : zip the output
-h : show help.
I tried few combinations with GetOptions which did not work for me.
So my question is: How to use GetOptions to handle this requirement?
EDIT: -z needs 'zip directory path'
EDIT2:
My script has following compulsory command-line arguments:
-in input_dir_path : Input directory
-out output_dir_path : Output directory
Here's my code:
my %args;
GetOptions(\%args,
"in=s",
"out=s"
) or die &usage();
die "Missing -in!" unless $args{in};
die "Missing -out!" unless $args{out};
Hope this EDIT adds more clarity.
A : (colon) can be used to indicate optional options:
#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;
my ( $zip, $help, $input_dir, $output_dir );
GetOptions(
'z:s' => \$zip,
'h' => \$help,
'in=s' => \$input_dir,
'out=s' => \$output_dir,
);
From the documentation:
: type [ desttype ]
Like "=", but designates the argument as optional. If omitted, an
empty string will be assigned to string values options, and the
value zero to numeric options.
If you specify that and check for the empty string, you know which ones the user did not specify.
This should set to 1 or 0 the values of $zip_output and $show_help based on what input arguments you get in command line.
use strict;
use warnings;
use Getopt::Long;
my $zip_output;
my $show_help;
GetOptions("z" => \$zip, "h" => \$show_help);