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 arbitrary
264 filehandle redirection before executing the command. This can be a
265 very convenient way to do shell-like filehandle plumbing.
266
267 For example;
268
269 run( -in => sub { print "Hello, world!\n" },
270 -out => "/tmp/outfile",
271 -out2 => "/dev/null",
272 @command );
273
274 This will connect the child process' standard input ("-in") to a
275 closure that is printing ""Hello, world!\n"". The output from the
276 closure will appear on standard input of the run command. Note
277 that the closure is run in a sub-process and so will not be able to
278 set variables in the calling program.
279
280 It will also connect the program's standard output ("-out") to
281 "/tmp/outfile", and its standard error (filehandle 2) to
282 "/dev/null" (the traditional way of junking error output).
283
284 If you wanted to connect two filehandles to the same place, you
285 could pass in "GLOB" references instead;
286
287 run( -out => \*MYOUT,
288 -out2 => \*MYOUT,
289 @command );
290
291 Any filehandle can be opened in any mode; "-in" merely defaults to
292 meaning "-in0", and "-out" defaults to meaning "-out1". There is
293 no "-err"; use "-out2". "-rw" exists (defaulting to "-rw0"), but
294 is probably of limited use.
295
296 Here is an example of using prompt_passwd() to hijack "gpg"'s
297 password grabbing;
298
299 my $password = prompt_passwd("Encryption password: ");
300 my $encrypted = run( -in4 => sub { print "$password\n" },
301 "gpg", "--passphrase-fd", "4", "-c", $file )
302
303 run_err("command", "arg2", "arg1")
304 Same as run, but returns the error code rather than assuming that
305 the command will successfully complete. Again, output it
306 suppressed.
307
308 capture("command", "1gra", "2gra")
309 runs a command, capturing its output, barfs if there is a problem.
310 Returns the output of the command as a list or a scalar.
311
312 capture_err("command", "foo")
313 Works as capture, but the first returned item is the error code of
314 the command ($?) rather than the first line of its output. Also,
315 it only ever returns the output as a list.
316
317 Usage:
318
319 my ($rc, @output) = capture_err("somecommand", @args);
320
321 hush_exec()
322 unhush_exec()
323 "hush_exec" is used to indicate that the programs you are running
324 are only of interest to someone debugging the script. So, the
325 messages showing commands run and giving execution timings will not
326 be printed without "-vv" (double verbose) or "-d" (debug, which is
327 the same thing).
328
329 start_timer()
330 show_delta()
331 show_elapsed()
332 These three little functions are for printing run times in your
333 scripts. Times are displayed for running external programs with
334 verbose mode normally, but this will let you display running times
335 for your main program easily.
336
337 sci_unit($num, [$unit, $precision])
338 Returns a number, scaled using normal scientific prefixes (from
339 atto to exa). Optionally specify a precision which is passed to
340 sprintf() (see "sprintf" in perldoc). The default is three
341 significant figures.
342
343 From Scriptalicious 1.08, the "u" character is used in place of the
344 Greek "mu" due to encoding compatibility issues.
345
346 time_unit($num, [$precision])
347 Converts a floating point number of seconds to a human-readable
348 time, the precision specifies the number of significant decimal
349 digits, which is used to compute a "quanta" for the value given,
350 values below which are not displayed. $precision defaults to 4.
351
352 examples:
353
354 time_unit(10.1) => "10.10s"
355 time_unit(1) => "1.000s"
356 time_unit(0.1) => "100ms"
357 time_unit(86401,2) => "1d 0h"
358 time_unit(86401,3) => "1d 0h"
359 time_unit(86401) => "1d 0h:0m"
360 time_unit(86400+3600/2) => "1d 0h:30m"
361 time_unit(86401,5) => "1d 0h:0m:1s"
362 time_unit(7*86400) => "1w0d 0h"
363 time_unit(-0.0002) => "-200us"
364
365 prompt_regex($prompt, qr/(.*)/)
366 Prompts for something, using the prompt "$prompt", matching the
367 entered value (sans trailing linefeed) against the passed regex.
368
369 Note that this differs from the previous behaviour of prompt_regex,
370 which took a sub.
371
372 prompt_sub($prompt, sub { /(.*)/ && $1 })
373 Prompts for something, using the prompt "$prompt", feeding the sub
374 with the entered value (sans trailing linefeed), to use a default,
375 the passed sub should simply return it with empty input.
376
377 prompt_passwd([$prompt])
378 Same as "prompt_regex", but turns off echo. $prompt defaults to
379 ""Password: "" for this function.
380
381 prompt_string([$prompt])
382 Prompt for a string.
383
384 prompt_int([$prompt])
385 get an integer
386
387 prompt_for([ [$type =] $what])>
388 Prompts for a value for $what. This constructs a prompt saying, eg
389 ""Enter value for $what"". Calls the equivalent prompt_foo()
390 method.
391
392 prompt_yn([$prompt])
393 prompts for yes or no, presuming neither
394
395 prompt_Yn([$prompt])
396 prompt_yN([$prompt])
397 prompts for yes or no, presuming yes and no, respectively.
398
399 You can also spell these as "prompt_nY" and "prompt_Ny".
400
401 anydump($ref)
402 Dump $ref via "YAML", falling back to "Data::Dumper" if YAML fails
403 to load (or dies during the dump). Returns a string.
404
405 tsay($template, $vars)
406 Prints the template $template with $vars. $template may be
407 included at the end of the file as a data section, for instance:
408
409 use Scriptalicious;
410
411 tsay hello => { name => "Bernie" };
412
413 __END__
414
415 __hello__
416 Hello, [% name %]
417 [% INCLUDE yomomma %]
418 __yomomma__
419 Yo momma's so fat your family portrait has stretchmarks.
420
421 This will print:
422
423 Hello, Bernie
424 Yo momma's so fat your family portrait has stretchmarks.
425
426 Note that the script goes to lengths to make sure that the
427 information is always printed whether or not Template Toolkit is
428 installed. This gets pretty verbose, but at least solves the
429 "argh! that script failed, but I don't know why because it needed
430 this huge dependancy to tell me" problem.
431
432 For example, the above would be printed as:
433
434 scriptname:
435
436 foo()
437 If you've got a short little Perl function that implements
438 something useful for people writing Shell scripts in Perl, then
439 please feel free to contribute it. And if it really is
440 scriptalicious, you can bet your momma on it getting into this
441 module!
442
444 Simon Cozen's Getopt::Auto module does a very similar thing to this
445 module, in a quite different way. However, it is missing "say", "run",
446 etc. So you'll need to use some other module for those. But it does
447 have some other features you might like and is probably engineered
448 better.
449
450 There's a template script at "Documentation and help texts" in
451 Getopt::Long that contains a script template that demonstrates what is
452 necessary to get the basic man page / usage things working with the
453 traditional Getopt::Long and Pod::Usage combination.
454
455 Getopt::Plus is a swiss army chainsaw of Getopt::* style modules,
456 contrasting to this module's approach of elegant simplicity (quiet in
457 the cheap seats!).
458
459 Getopt::EUCLID is Damian Conway's take on this.
460
461 Finally, if you don't mind the dependencies of Moose (or Mouse), then
462 MooseX::Getopt and MooseX::SimpleConfig are much more elegant
463 approaches to getopt handling and configuration than this module.
464
465 If you have solved this problem in a new and interesting way, or even
466 rehashed it in an old, boring and inelegant way and want your module to
467 be listed here, please contact the
468
470 Sam Vilain, samv@cpan.org
471
472 Copyright 2005-2008, Sam Vilain. All rights reserved. This program is
473 free software; you can use it and/or distribute it under the same terms
474 as Perl itself; either the latest stable release of Perl when the
475 module was written, or any subsequent stable release.
476
477 Please note that this applies retrospectively to all Scriptalicious
478 releases; apologies for the lack of an explicit license.
479
480
481
482perl v5.36.0 2023-01-20 Scriptalicious(3)