1Scriptalicious(3)     User Contributed Perl Documentation    Scriptalicious(3)
2
3
4

NAME

6       Scriptalicious - Make scripts more delicious to SysAdmins
7

SYNOPSIS

9        use Scriptalicious
10             -progname => "pu";
11
12        our $VERSION = "1.00";
13
14        my $url = ".";
15        getopt getconf("u|url" => \$url);
16
17        run("echo", "doing something with $url");
18        my $output = capture("svn", "info", $url);
19
20        __END__
21
22        =head1 NAME
23
24        pu - an uncarved block of wood
25
26        =head1 SYNOPSIS
27
28        pu [options] arguments
29
30        =head1 DESCRIPTION
31
32        This script's function is to be a blank example that many
33        great and simple scripts may be built upon.
34
35        Remember, you cannot carve rotten wood.
36
37        =head1 COMMAND LINE OPTIONS
38
39        =over
40
41        =item B<-h, --help>
42
43        Display a program usage screen and exit.
44
45        =item B<-V, --version>
46
47        Display program version and exit.
48
49        =item B<-v, --verbose>
50
51        Verbose command execution, displaying things like the
52        commands run, their output, etc.
53
54        =item B<-q, --quiet>
55
56        Suppress all normal program output; only display errors and
57        warnings.
58
59        =item B<-d, --debug>
60
61        Display output to help someone debug this script, not the
62        process going on.
63
64        =back
65

DESCRIPTION

67       This module helps you write scripts that conform to best common
68       practices, quickly.  Just include the above as a template, and your
69       script will accept all of the options that are included in the manual
70       page, as well as summarising them when you use the "-h" option.
71
72       (Unfortunately, it is not possible to have a `use' dependency
73       automatically add structure to your POD yet, so you have to include the
74       above manually.  If you want your help message and Perldoc to be
75       meaningful, that is.)
76
77       Shortcuts are provided to help you abort or die with various error
78       conditions; all of which print the name of the program running (taken
79       from $0 if not passed).  The motive for this is that "small" scripts
80       tend to just get written and forgotten; so, when you have a larger
81       system that is built out of lots of these pieces it is sometimes
82       guesswork figuring out which script a printed message comes from!
83
84       For instance, if your program is called with invalid arguments, you may
85       simply call "abort" with a one-line message saying what the particular
86       problem was.  When the script is run, it will invite the person running
87       the script to try to use the "--help" option, which gives them a
88       summary and in turn invites them to read the Perldoc.  So, it reads
89       well in the source;
90
91         @ARGV and abort "unexpected arguments: @ARGV";
92         $file or abort "no filename supplied";
93
94       And in the output;
95
96         somescript: no filename supplied!
97         Try `somescript --help' for a summary of options
98
99       On the other hand, if you call "barf", then it is considered to be a
100       hard run-time failure, and the invitation to read the "--help" page to
101       get usage not given.  Also, the messages are much tidier than you get
102       with "die" et al.
103
104         open FOO, "<$file" or barf "failed to open $file; $!";
105
106       Which will print:
107
108         somescript: failed to open somefile; Permission denied
109
110       Scriptalicious has no hard dependancies; all the methods, save reading
111       passwords from the user, will work in the absence of extra installed
112       modules on all versions of Perl from 5.6.0 onwards.
113
114       To avoid unnecessary explicit importing of symbols, the following
115       symbols and functions are exported into the caller's namespace:
116
117       $VERBOSE
118           Set to 0 by default, and 1 if "-v" or "--verbose" was found during
119           the call to "getopt()".  Extra "-v"'s or "--debug" will push this
120           variable higher.  If "-q" or "--quiet" is specified, this will be
121           less than one.
122
123       $PROGNAME
124           It is recommended that you only ever read this variable, and pass
125           it in via the import.  This is not automatically extracted from the
126           POD for performance reasons.
127
128       $CONFIG
129           Name of the configuration file.  Set before a call to "getconf", or
130           read afterwards to see if a config file was used.  New in
131           Scriptalicious 1.16
132
133       getopt(@getopt_args)
134           Fetch arguments via "Getopt::Long::GetOptions".  The "bundling"
135           option is enabled by default - which differs from the standard
136           configuration of Getopt::Long.  To alter the configuration, simply
137           call "Getopt::Long::config".  See Getopt::Long for more
138           information.
139
140       getopt_lenient(@getopt_args)
141           Just like "getopt()", but doesn't cause a fatal error if there are
142           any unknown options.
143
144       getconf(@getopt_args)
145           Fetches configuration, takes arguments in the same form as
146           getopt()..
147
148           The configuration file is expected to be in ~/.PROGNAMErc,
149           /etc/perl/PROGNAME.conf, or /etc/PROGNAME.conf.  Only the first
150           found file is read, and unknown options are ignored for the time
151           being.
152
153           The file is expected to be in YAML format, with the top entity
154           being a hash, and the keys of the hash being the same as specifying
155           options on the command line.  Using YAML as a format allows some
156           simplificiations to getopt-style processing - "=s%" and "=s@" style
157           options are expected to be in a real hash or list format in the
158           config file, and boolean options must be set to "true" or "false"
159           (or some common equivalents).
160
161           Returns the configuration file as Load()'ed by YAML in scalar
162           context, or the argument list it was passed in list context.
163
164           For example, this minimal script (missing the documentation, but
165           hey at least it's a start);
166
167             getopt getconf
168                 ( "something|s" => \$foo,
169                   "invertable|I!" => \$invertable,
170                   "integer|i=i" => \$bar,
171                   "string|s=s" => \$cheese,
172                   "list|l=s@" => \@list,
173                   "hash|H=s%" => \%hash, );
174
175           Will accept the following invocation styles;
176
177             foo.pl --help
178             foo.pl --version
179             foo.pl --verbose
180             foo.pl --debug
181             foo.pl --quiet
182
183             foo.pl --something
184             foo.pl --invertable
185             foo.pl --no-invertable    <=== FORM DIFFERS IN CONFIG FILE
186             foo.pl --integer=7
187             foo.pl --string=anything
188             foo.pl --list one --list two --list three
189             foo.pl --hash foo=bar --hash baz=cheese
190
191           Equivalent config files:
192
193             something: 1
194
195             invertable: on
196
197             invertable: off
198
199             integer: 7
200
201             string: anything
202
203             list:
204               - one
205               - two
206               - three
207
208             list: [ one, two, three ]
209
210             hash:
211               foo: bar
212               baz: cheese
213
214           Note that more complex and possibly arcane usages of Getopt::Long
215           features may not work with getconf (patches welcome).
216
217           This can be handy for things like database connection strings; all
218           you have to do is make an option for them, and then the user of the
219           script, or a SysAdmin can set up their own config file for the
220           script to automatically set the options.
221
222       getconf_f($filename, @getopt_args)
223           As getconf(), but specify a filename.
224
225       say "something"
226           Prints a message to standard output, unless quiet mode ("-q" or
227           "--quiet") was specified.  For normal program messages.
228
229       mutter "progress"
230           Prints a message to standard output, if verbose mode ("-v") or
231           debug mode ("-d") is enabled (ie, if "$VERBOSE > 0").  For messages
232           designed to help a user of the script to see more information about
233           what is going on.
234
235       whisper "detail"
236           Prints a message to standard output, if debug mode ("-d") is
237           enabled or multiple verbose options were passed (ie, if "$VERBOSE >
238           1").  For messages designed to help a person debugging the script
239           to see more information about what is going on internally to the
240           script.
241
242       abort "won't go to sea in a storm"
243           Prints a short program usage message (extracted from the POD
244           synopsis) and exits with an error code.
245
246       moan "weather is miserable"
247           Prints a warning to standard error.  It is preceded with the text
248           "warning:".  The program does not exit.
249
250       protest "don't know the weather report"
251           Prints an error message to standard error.  It is preceded with the
252           text "error:".  The program does not exit.
253
254       barf "hit an iceberg"
255           Prints a warning to standard error.  It is preceded with the text
256           "warning:".  The program does not exit.
257
258       run("command", "arg1", "arg2")
259           Runs a command or closure, barf's with a relevant error message if
260           there is a problem.  Program output is suppressed unless running in
261           verbose mode.
262
263           "run()" and the three alternatives listed below may perform
264           arbitrary filehandle redirection before executing the command.
265           This can be a very convenient way to do shell-like filehandle
266           plumbing.
267
268           For example;
269
270             run( -in => sub { print "Hello, world!\n" },
271                  -out => "/tmp/outfile",
272                  -out2 => "/dev/null",
273                  @command );
274
275           This will connect the child process' standard input ("-in") to a
276           closure that is printing ""Hello, world!\n"".  The output from the
277           closure will appear on standard input of the run command.  Note
278           that the closure is run in a sub-process and so will not be able to
279           set variables in the calling program.
280
281           It will also connect the program's standard output ("-out") to
282           "/tmp/outfile", and its standard error (filehandle 2) to
283           "/dev/null" (the traditional way of junking error output).
284
285           If you wanted to connect two filehandles to the same place, you
286           could pass in "GLOB" references instead;
287
288             run( -out => \*MYOUT,
289                  -out2 => \*MYOUT,
290                  @command );
291
292           Any filehandle can be opened in any mode; "-in" merely defaults to
293           meaning "-in0", and "-out" defaults to meaning "-out1".  There is
294           no "-err"; use "-out2".  "-rw" exists (defaulting to "-rw0"), but
295           is probably of limited use.
296
297           Here is an example of using "prompt_passwd()" to hijack "gpg"'s
298           password grabbing;
299
300             my $password = prompt_passwd("Encryption password: ");
301             my $encrypted = run( -in4 => sub { print "$password\n" },
302                                  "gpg", "--passphrase-fd", "4", "-c", $file )
303
304       run_err("command", "arg2", "arg1")
305           Same as run, but returns the error code rather than assuming that
306           the command will successfully complete.  Again, output it
307           suppressed.
308
309       capture("command", "1gra", "2gra")
310           runs a command, capturing its output, barfs if there is a problem.
311           Returns the output of the command as a list or a scalar.
312
313       capture_err("command", "foo")
314           Works as capture, but the first returned item is the error code of
315           the command ($?) rather than the first line of its output.  Also,
316           it only ever returns the output as a list.
317
318           Usage:
319
320              my ($rc, @output) = capture_err("somecommand", @args);
321
322       hush_exec()
323       unhush_exec()
324           "hush_exec" is used to indicate that the programs you are running
325           are only of interest to someone debugging the script.  So, the
326           messages showing commands run and giving execution timings will not
327           be printed without "-vv" (double verbose) or "-d" (debug, which is
328           the same thing).
329
330       start_timer()
331       show_delta()
332       show_elapsed()
333           These three little functions are for printing run times in your
334           scripts.  Times are displayed for running external programs with
335           verbose mode normally, but this will let you display running times
336           for your main program easily.
337
338       sci_unit($num, [$unit, $precision])
339           Returns a number, scaled using normal scientific prefixes (from
340           atto to exa).  Optionally specify a precision which is passed to
341           sprintf() (see "sprintf" in perldoc).  The default is three
342           significant figures.
343
344           From Scriptalicious 1.08, the "u" character is used in place of the
345           Greek "mu" due to encoding compatibility issues.
346
347       time_unit($num, [$precision])
348           Converts a floating point number of seconds to a human-readable
349           time, the precision specifies the number of significant decimal
350           digits, which is used to compute a "quanta" for the value given,
351           values below which are not displayed.  $precision defaults to 4.
352
353           examples:
354
355            time_unit(10.1) => "10.10s"
356            time_unit(1) => "1.000s"
357            time_unit(0.1) => "100ms"
358            time_unit(86401,2) => "1d 0h"
359            time_unit(86401,3) => "1d 0h"
360            time_unit(86401) => "1d 0h:0m"
361            time_unit(86400+3600/2) => "1d 0h:30m"
362            time_unit(86401,5) => "1d 0h:0m:1s"
363            time_unit(7*86400) => "1w0d 0h"
364            time_unit(-0.0002) => "-200us"
365
366       prompt_regex($prompt, qr/(.*)/)
367           Prompts for something, using the prompt "$prompt", matching the
368           entered value (sans trailing linefeed) against the passed regex.
369
370           Note that this differs from the previous behaviour of prompt_regex,
371           which took a sub.
372
373       prompt_sub($prompt, sub { /(.*)/ && $1 })
374           Prompts for something, using the prompt "$prompt", feeding the sub
375           with the entered value (sans trailing linefeed), to use a default,
376           the passed sub should simply return it with empty input.
377
378       prompt_passwd([$prompt])
379           Same as "prompt_regex", but turns off echo.  $prompt defaults to
380           ""Password: "" for this function.
381
382       prompt_string([$prompt])
383           Prompt for a string.
384
385       prompt_int([$prompt])
386           get an integer
387
388       prompt_for([ [$type =] $what])>
389           Prompts for a value for $what.  This constructs a prompt saying, eg
390           ""Enter value for $what"".  Calls the equivalent "prompt_foo()"
391           method.
392
393       prompt_yn([$prompt])
394           prompts for yes or no, presuming neither
395
396       prompt_Yn([$prompt])
397       prompt_yN([$prompt])
398           prompts for yes or no, presuming yes and no, respectively.
399
400           You can also spell these as "prompt_nY" and "prompt_Ny".
401
402       anydump($ref)
403           Dump $ref via "YAML", falling back to "Data::Dumper" if YAML fails
404           to load (or dies during the dump).  Returns a string.
405
406       tsay($template, $vars)
407           Prints the template $template with $vars.  $template may be
408           included at the end of the file as a data section, for instance:
409
410            use Scriptalicious;
411
412            tsay hello => { name => "Bernie" };
413
414            __END__
415
416            __hello__
417            Hello, [% name %]
418            [% INCLUDE yomomma %]
419            __yomomma__
420            Yo momma's so fat your family portrait has stretchmarks.
421
422           This will print:
423
424            Hello, Bernie
425            Yo momma's so fat your family portrait has stretchmarks.
426
427           Note that the script goes to lengths to make sure that the
428           information is always printed whether or not Template Toolkit is
429           installed.  This gets pretty verbose, but at least solves the
430           "argh!  that script failed, but I don't know why because it needed
431           this huge dependancy to tell me" problem.
432
433           For example, the above would be printed as:
434
435            scriptname:
436
437       foo()
438           If you've got a short little Perl function that implements
439           something useful for people writing Shell scripts in Perl, then
440           please feel free to contribute it.  And if it really is
441           scriptalicious, you can bet your momma on it getting into this
442           module!
443

SEE ALSO

445       Simon Cozen's Getopt::Auto module does a very similar thing to this
446       module, in a quite different way.  However, it is missing "say", "run",
447       etc.  So you'll need to use some other module for those.  But it does
448       have some other features you might like and is probably engineered
449       better.
450
451       There's a template script at "Documentation and help texts" in
452       Getopt::Long that contains a script template that demonstrates what is
453       necessary to get the basic man page / usage things working with the
454       traditional Getopt::Long and Pod::Usage combination.
455
456       Getopt::Plus is a swiss army chainsaw of Getopt::* style modules,
457       contrasting to this module's approach of elegant simplicity (quiet in
458       the cheap seats!).
459
460       Getopt::EUCLID is Damian Conway's take on this.
461
462       Finally, if you don't mind the dependencies of Moose (or Mouse), then
463       MooseX::Getopt and MooseX::SimpleConfig are much more elegant
464       approaches to getopt handling and configuration than this module.
465
466       If you have solved this problem in a new and interesting way, or even
467       rehashed it in an old, boring and inelegant way and want your module to
468       be listed here, please contact the
469

AUTHOR AND LICENSE

471       Sam Vilain, samv@cpan.org
472
473       Copyright 2005-2008, Sam Vilain.  All rights reserved.  This program is
474       free software; you can use it and/or distribute it under the same terms
475       as Perl itself; either the latest stable release of Perl when the
476       module was written, or any subsequent stable release.
477
478       Please note that this applies retrospectively to all Scriptalicious
479       releases; apologies for the lack of an explicit license.
480
481
482
483perl v5.32.1                      2021-01-27                 Scriptalicious(3)
Impressum