1Scriptalicious(3) User Contributed Perl Documentation Scriptalicious(3)
2
3
4
6 Scriptalicious - Make scripts more delicious to SysAdmins
7
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
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
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
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.36.0 2022-07-22 Scriptalicious(3)