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.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.