Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Getopt::Long

by Anonymous Monk
on May 28, 2004 at 22:54 UTC ( #357384=note: print w/replies, xml ) Need Help??


in reply to Getopt::Long

i think this is close to what you want. it's not complete or nice, just a test of doablility.

alot of my scripts share common command line args that are a pain to maintain with cut and paste.

  • everything gets a --help and --man that reads pod from the current file or from a specific pod.
  • almost everything works against a list of hosts. hosts can be in files given by --file or specified individually by --host or any combination. even --host foo,blah,bling --list bam.lst,wiz.lst --host thistoo.
  • most things require passwords which can usually be fetched from a database, but in the worst case scenerios there needs to be a way to specify all needed passwords by options, --password snmp.ro=bling --password snmp.rw=blah --password cisco.console=foo.
and those are just the basics, some things need database options, some need accounting options, some need more options than you can shake a stick at.

so i started to wrap them up into modules. you probably only need to check the docs for the pass_through option.

package DNO::Options; use strict; use Exporter (); use vars qw( @ISA @EXPORT @EXPORT_OK ); @ISA = qw( Exporter ); @EXPORT = qw( get_options ); @EXPORT_OK = qw( uncommify ); use Getopt::Long qw( :config pass_through ); sub uncommify { my $aref = shift; return split /,/, join ',', @$aref; } sub get_options { my $def = shift; my $cur = {}; $cur->{$_->[0]} = $_->[2] for @$def; my @def = map {$_->[0].$_->[1]} @$def; GetOptions( $cur, @def ); return $cur; } 1; package DNO::Passwords; use strict; use vars qw( @ISA @EXPORT ); @ISA = qw( Exporter ); @EXPORT = qw( passwords ); use DNO::Options qw( get_options ); use DNO::Documentation qw( usage ); my ($def, $opt); $def = [ [ 'password', '=s%', {} ], ]; sub passwords { my ( @want ) = @_; $opt = get_options( $def ); my %pw = map { $_ => undef } @want; $pw{$_} = $opt->{password}{$_} for keys %{ $opt->{password} }; my @need = grep { not defined $pw{$_} } keys %pw; if ( @need ) { require DNO::Util; DNO::Util->import( qw/ get_passwords / ); my $pw = get_passwords( @need ); unless ( defined $pw ) { usage( -verbose => 1, -message => "$0 +: no passwords. did you kinit?$/" ); } $pw{$_} = $pw->{$_} for @need; @need = grep { not defined $pw{$_} } keys %pw; } if ( @need ) { usage( -verbose => 1, -message => "$0: missing pass +words: @need$/" ); } return \%pw; } 1; package DNO::Devices; use strict; use vars qw( @ISA @EXPORT @EXPORT_OK ); @ISA = qw( Exporter ); @EXPORT = qw( devices ); @EXPORT_OK = qw( ); use DNO::Options qw( get_options uncommify ); use DNO::Documentation qw( usage ); my ($def, $opt); my @hosts; $def = [ [ 'host', '=s@', [] ], [ 'list', '=s@', [] ], ]; sub devices { $opt = get_options( $def ); foreach my $file ( uncommify($opt->{list}) ) { local *F; open F, '<', $file or usage( -verbose => 1, -message => "$0: open $file: $!$/") +; while ( <F> ) { s/#.*//; next if /^\s*$/; push @hosts, (split)[0]; } close F; } push @hosts, uncommify($opt->{host}); #unless ( @hosts ) { usage( -verbose => 1, -message => "$0: no dev +ices to work with.$/" ); } return @hosts; } 1; package DNO::Documentation; use strict; # Globals use vars qw( @ISA @EXPORT @EXPORT_OK %INC ); # Exports @ISA = qw( Exporter ); @EXPORT = qw( usage ); @EXPORT_OK = qw( doc_setup ); # Use use Pod::Usage; use DNO::Options qw( get_options ); # Options definitions my ($def, $opt); $def = [ [ 'help', '', 0 ], [ 'man', '', 0 ], ]; # Class Data my %Default = ( ); # Find our documentation directory and add to searchpath my $class = __PACKAGE__ . '.pm'; $class =~ s/::/\//g; my $path = $INC{$class}; $path =~ s/\.pm$//; $Default{'-pathlist'} = "$path:$ENV{PATH}"; 1;

and a script that uses the modules can now look like this.

#!/usr/bin/perl use strict; use warnings; $|++; #use Data::Dumper; use lib '../lib'; use DNO::Documentation qw( doc_setup usage ); doc_setup(); use DNO::Passwords qw( passwords ); my $pw = passwords( qw/ snmp.ro / ); #print Dumper($pw); use DNO::Devices qw( devices ); my @hosts = devices(); #print Dumper(\@hosts); use DNO::Options qw( get_options ); my ($def, $opt); $def = [ [ 'maxfork', '=i', 20 ], [ 'timeout', '=i', 2 ], [ 'retries', '=i', 2 ], ]; $opt = get_options( $def ); # ... do something __END__ $ dosumthin --host mary --list domain1,domain3 --password snmp.ro=publ +ic --timeout 5 --retries 4

there are probably better ways to accomplish the same thing. but it is nice that i only have to have a few ugly lines in each script to handle the docs, the hosts, the passwords, ... instead of a huge getopts in each script.

Replies are listed 'Best First'.
Re: Re: Getopt::Long
by david.shin (Initiate) on Jun 01, 2004 at 13:58 UTC
    Thanks for the code snippet, but simpler is better for now.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://357384]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (7)
As of 2022-01-19 14:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:












    Results (55 votes). Check out past polls.

    Notices?