1Sysadm::Install(3)    User Contributed Perl Documentation   Sysadm::Install(3)
2
3
4

NAME

6       Sysadm::Install - Typical installation tasks for system administrators
7

SYNOPSIS

9         use Sysadm::Install qw(:all);
10
11         my $INST_DIR = '/home/me/install/';
12
13         cd($INST_DIR);
14         cp("/deliver/someproj.tgz", ".");
15         untar("someproj.tgz");
16         cd("someproj");
17
18            # Write out ...
19         blurt("Builder: Mike\nDate: Today\n", "build.dat");
20
21            # Slurp back in ...
22         my $data = slurp("build.dat");
23
24            # or edit in place ...
25         pie(sub { s/Today/scalar localtime()/ge; $_; }, "build.dat");
26
27         make("test install");
28
29            # run a cmd and tap into stdout and stderr
30         my($stdout, $stderr, $exit_code) = tap("ls", "-R");
31

DESCRIPTION

33       Have you ever wished for your installation shell scripts to run
34       reproducibly, without much programming fuzz, and even with optional
35       logging enabled? Then give up shell programming, use Perl.
36
37       "Sysadm::Install" executes shell-like commands performing typical
38       installation tasks: Copying files, extracting tarballs, calling "make".
39       It has a "fail once and die" policy, meticulously checking the result
40       of every operation and calling "die()" immediately if anything fails.
41
42       "Sysadm::Install" also supports a dry_run mode, in which it logs
43       everything, but suppresses any write actions. Dry run mode is enabled
44       by calling Sysadm::Install::dry_run(1). To switch back to normal, call
45       Sysadm::Install::dry_run(0).
46
47       As of version 0.17, "Sysadm::Install" supports a confirm mode, in which
48       it interactively asks the user before running any of its functions
49       (just like "rm -i"). confirm mode is enabled by calling
50       Sysadm::Install::confirm(1). To switch back to normal, call
51       Sysadm::Install::confirm(0).
52
53       "Sysadm::Install" is fully Log4perl-enabled. To start logging, just
54       initialize "Log::Log4perl". "Sysadm::Install" acts as a wrapper class,
55       meaning that file names and line numbers are reported from the calling
56       program's point of view.
57
58   FUNCTIONS
59       "cp($source, $target)"
60           Copy a file from $source to $target. "target" can be a directory.
61           Note that "cp" doesn't copy file permissions. If you want the
62           target file to reflect the source file's user rights, use
63           "perm_cp()" shown below.
64
65       "mv($source, $target)"
66           Move a file from $source to $target. "target" can be a directory.
67
68       "download($url)"
69           Download a file specified by $url and store it under the name
70           returned by "basename($url)".
71
72       "untar($tarball)"
73           Untar the tarball in $tarball, which typically adheres to the
74           "someproject-X.XX.tgz" convention.  But regardless of whether the
75           archive actually contains a top directory "someproject-X.XX", this
76           function will behave if it had one. If it doesn't have one, a new
77           directory is created before the unpacking takes place. Unpacks the
78           tarball into the current directory, no matter where the tarfile is
79           located.  Please note that if you're using a compressed tarball
80           (.tar.gz or .tgz), you'll need IO::Zlib installed.
81
82       "untar_in($tar_file, $dir)"
83           Untar the tarball in $tgz_file in directory $dir. Create $dir if it
84           doesn't exist yet.
85
86       "pick($prompt, $options, $default, $opts)"
87           Ask the user to pick an item from a displayed list. $prompt is the
88           text displayed, $options is a referenc to an array of choices, and
89           $default is the number (starting from 1, not 0) of the default
90           item. For example,
91
92               pick("Pick a fruit", ["apple", "pear", "pineapple"], 3);
93
94           will display the following:
95
96               [1] apple
97               [2] pear
98               [3] pineapple
99               Pick a fruit [3]>
100
101           If the user just hits Enter, "pineapple" (the default value) will
102           be returned. Note that 3 marks the 3rd element of the list, and is
103           not an index value into the array.
104
105           If the user enters 1, 2 or 3, the corresponding text string
106           ("apple", "pear", "pineapple" will be returned by "pick()".
107
108           If the optional $opts hash has "{ tty => 1 }" set, then the user
109           response will be expected from the console, not STDIN.
110
111       "ask($prompt, $default, $opts)"
112           Ask the user to either hit Enter and select the displayed default
113           or to type in another string.
114
115           If the optional $opts hash has "{ tty => 1 }" set, then the user
116           response will be expected from the console, not STDIN.
117
118       "mkd($dir)"
119           Create a directory of arbitrary depth, just like
120           "File::Path::mkpath".
121
122       "rmf($dir)"
123           Delete a directory and all of its descendents, just like "rm -rf"
124           in the shell.
125
126       "cd($dir)"
127           chdir to the given directory. If you don't want to have cd() modify
128           the internal directory stack (used for subsequent cdback() calls),
129           set the stack_update parameter to a false value:
130
131               cd($dir, {stack_update => 0});
132
133       "cdback()"
134           chdir back to the last directory before a previous "cd". If the
135           option "reset" is set, it goes all the way back to the beginning of
136           the directory stack, i.e. no matter how many cd() calls were made
137           in between, it'll go back to the original directory:
138
139                 # go all the way back
140               cdback( { reset => 1 } );
141
142       "make()"
143           Call "make" in the shell.
144
145       "pie($coderef, $filename, ...)"
146           Simulate "perl -pie 'do something' file". Edits files in-place.
147           Expects a reference to a subroutine as its first argument. It will
148           read out the file $filename line by line and calls the subroutine
149           setting a localized $_ to the current line. The return value of the
150           subroutine will replace the previous value of the line.
151
152           Example:
153
154               # Replace all 'foo's by 'bar' in test.dat
155                   pie(sub { s/foo/bar/g; $_; }, "test.dat");
156
157           Works with one or more file names.
158
159           If the files are known to contain UTF-8 encoded data, and you want
160           it to be read/written as a Unicode strings, use the "utf8" option:
161
162               pie(sub { s/foo/bar/g; $_; }, "test.dat", { utf8 => 1 });
163
164       "plough($coderef, $filename, ...)"
165           Simulate "perl -ne 'do something' file". Iterates over all lines of
166           all input files and calls the subroutine provided as the first
167           argument.
168
169           Example:
170
171               # Print all lines containing 'foobar'
172                   plough(sub { print if /foobar/ }, "test.dat");
173
174           Works with one or more file names.
175
176           If the files are known to contain UTF-8 encoded data, and you want
177           it to be read into Unicode strings, use the "utf8" option:
178
179               plough(sub { print if /foobar/ }, "test.dat", { utf8 => 1 });
180
181       "my $data = slurp($file, $options)"
182           Slurps in the file and returns a scalar with the file's content. If
183           called without argument, data is slurped from STDIN or from any
184           files provided on the command line (like <> operates).
185
186           If the file is known to contain UTF-8 encoded data and you want to
187           read it in as a Unicode string, use the "utf8" option:
188
189               my $unicode_string = slurp( $file, {utf8 => 1} );
190
191       "blurt($data, $file, $options)"
192           Opens a new file, prints the data in $data to it and closes the
193           file.  If "$options->{append}" is set to a true value, data will be
194           appended to the file. Default is false, existing files will be
195           overwritten.
196
197           If the string is a Unicode string, use the "utf8" option:
198
199               blurt( $unicode_string, $file, {utf8 => 1} );
200
201       "blurt_atomic($data, $file, $options)"
202           Write the data in $data to a file $file, guaranteeing that the
203           operation will either complete fully or not at all. This is
204           accomplished by first writing to a temporary file which is then
205           rename()ed to the target file.
206
207           Unlike in "blurt", there is no $append mode in "blurt_atomic".
208
209           If the string is a Unicode string, use the "utf8" option:
210
211               blurt_atomic( $unicode_string, $file, {utf8 => 1} );
212
213       "($stdout, $stderr, $exit_code) = tap($cmd, @args)"
214           Run a command $cmd in the shell, and pass it @args as args.
215           Capture STDOUT and STDERR, and return them as strings. If
216           $exit_code is 0, the command succeeded. If it is different, the
217           command failed and $exit_code holds its exit code.
218
219           Please note that "tap()" is limited to single shell commands, it
220           won't work with output redirectors ("ls >/tmp/foo" 2>&1).
221
222           In default mode, "tap()" will concatenate the command and args
223           given and create a shell command line by redirecting STDERR to a
224           temporary file. "tap("ls", "/tmp")", for example, will result in
225
226               'ls' '/tmp' 2>/tmp/sometempfile |
227
228           Note that all commands are protected by single quotes to make sure
229           arguments containing spaces are processed as singles, and no
230           globbing happens on wildcards. Arguments containing single quotes
231           or backslashes are escaped properly.
232
233           If quoting is undesirable, "tap()" accepts an option hash as its
234           first parameter,
235
236               tap({no_quotes => 1}, "ls", "/tmp/*");
237
238           which will suppress any quoting:
239
240               ls /tmp/* 2>/tmp/sometempfile |
241
242           Or, if you prefer double quotes, use
243
244               tap({double_quotes => 1}, "ls", "/tmp/$VAR");
245
246           wrapping all args so that shell variables are interpolated
247           properly:
248
249               "ls" "/tmp/$VAR" 2>/tmp/sometempfile |
250
251           Another option is "utf8" which runs the command in a terminal set
252           to UTF8.
253
254           Error handling: By default, tap() won't raise an error if the
255           command's return code is nonzero, indicating an error reported by
256           the shell. If bailing out on errors is requested to avoid return
257           code checking by the script, use the raise_error option:
258
259               tap({raise_error => 1}, "ls", "doesn't exist");
260
261           In DEBUG mode, "tap" logs the entire stdout/stderr output, which
262           can get too verbose at times. To limit the number of bytes logged,
263           use the "stdout_limit" and "stderr_limit" options
264
265               tap({stdout_limit => 10}, "echo", "123456789101112");
266
267       "$quoted_string = qquote($string, [$metachars])"
268           Put a string in double quotes and escape all sensitive characters
269           so there's no unwanted interpolation.  E.g., if you have something
270           like
271
272              print "foo!\n";
273
274           and want to put it into a double-quoted string, it will look like
275
276               "print \"foo!\\n\""
277
278           Sometimes, not only backslashes and double quotes need to be
279           escaped, but also the target environment's meta chars. A string
280           containing
281
282               print "$<\n";
283
284           needs to have the '$' escaped like
285
286               "print \"\$<\\n\";"
287
288           if you want to reuse it later in a shell context:
289
290               $ perl -le "print \"\$<\\n\";"
291               1212
292
293           "qquote()" supports escaping these extra characters with its
294           second, optional argument, consisting of a string listing  all
295           escapable characters:
296
297               my $script  = 'print "$< rocks!\\n";';
298               my $escaped = qquote($script, '!$'); # Escape for shell use
299               system("perl -e $escaped");
300
301               => 1212 rocks!
302
303           And there's a shortcut for shells: By specifying ':shell' as the
304           metacharacters string, qquote() will actually use '!$`'.
305
306           For example, if you wanted to run the perl code
307
308               print "foobar\n";
309
310           via
311
312               perl -e ...
313
314           on a box via ssh, you would use
315
316               use Sysadm::Install qw(qquote);
317
318               my $cmd = 'print "foobar!\n"';
319                  $cmd = "perl -e " . qquote($cmd, ':shell');
320                  $cmd = "ssh somehost " . qquote($cmd, ':shell');
321
322               print "$cmd\n";
323               system($cmd);
324
325           and get
326
327               ssh somehost "perl -e \"print \\\"foobar\\\!\\\\n\\\"\""
328
329           which runs on "somehost" without hickup and prints "foobar!".
330
331           Sysadm::Install comes with a script "one-liner" (installed in bin),
332           which takes arbitrary perl code on STDIN and transforms it into a
333           one-liner:
334
335               $ one-liner
336               Type perl code, terminate by CTRL-D
337               print "hello\n";
338               print "world\n";
339               ^D
340               perl -e "print \"hello\\n\"; print \"world\\n\"; "
341
342       "$quoted_string = quote($string, [$metachars])"
343           Similar to "qquote()", just puts a string in single quotes and
344           escapes what needs to be escaped.
345
346           Note that shells typically don't support escaped single quotes
347           within single quotes, which means that
348
349               $ echo 'foo\'bar'
350               >
351
352           is invalid and the shell waits until it finds a closing quote.
353           Instead, there is an evil trick which gives the desired result:
354
355               $ echo 'foo'\''bar'  # foo, single quote, \, 2 x single quote, bar
356               foo'bar
357
358           It uses the fact that shells interpret back-to-back strings as one.
359           The construct above consists of three back-to-back strings:
360
361               (1) 'foo'
362               (2) '
363               (3) 'bar'
364
365           which all get concatenated to a single
366
367               foo'bar
368
369           If you call "quote()" with $metachars set to ":shell", it will
370           perform that magic behind the scenes:
371
372               print quote("foo'bar");
373                 # prints: 'foo'\''bar'
374
375       "perm_cp($src, $dst, ...)"
376           Read the $src file's user permissions and modify all $dst files to
377           reflect the same permissions.
378
379       "owner_cp($src, $dst, ...)"
380           Read the $src file/directory's owner uid and group gid and apply it
381           to $dst.
382
383           For example: copy uid/gid of the containing directory to a file
384           therein:
385
386               use File::Basename;
387
388               owner_cp( dirname($file), $file );
389
390           Usually requires root privileges, just like chown does.
391
392       "$perms = perm_get($filename)"
393           Read the $filename's user permissions and owner/group.  Returns an
394           array ref to be used later when calling "perm_set($filename,
395           $perms)".
396
397       "perm_set($filename, $perms)"
398           Set file permissions and owner of $filename according to $perms,
399           which was previously acquired by calling "perm_get($filename)".
400
401       "sysrun($cmd)"
402           Run a shell command via "system()" and die() if it fails. Also
403           works with a list of arguments, which are then interpreted as
404           program name plus arguments, just like "system()" does it.
405
406       "hammer($cmd, $arg, ...)"
407           Run a command in the shell and simulate a user hammering the ENTER
408           key to accept defaults on prompts.
409
410       "say($text, ...)"
411           Alias for "print ..., "\n"", just like Perl6 is going to provide
412           it.
413
414       "sudo_me()"
415           Check if the current script is running as root. If yes, continue.
416           If not, restart the current script with all command line arguments
417           is restarted under sudo:
418
419               sudo scriptname args ...
420
421           Make sure to call this before any @ARGV-modifying functions like
422           "getopts()" have kicked in.
423
424       "bin_find($program)"
425           Search all directories in $PATH (the ENV variable) for an
426           executable named $program and return the full path of the first
427           hit. Returns "undef" if the program can't be found.
428
429       "fs_read_open($dir)"
430           Opens a file handle to read the output of the following process:
431
432               cd $dir; find ./ -xdev -print0 | cpio -o0 |
433
434           This can be used to capture a file system structure.
435
436       "fs_write_open($dir)"
437           Opens a file handle to write to a
438
439               | (cd $dir; cpio -i0)
440
441           process to restore a file system structure. To be used in
442           conjunction with fs_read_open.
443
444       "pipe_copy($in, $out, [$bufsize])"
445           Reads from $in and writes to $out, using sysread and syswrite. The
446           buffer size used defaults to 4096, but can be set explicitly.
447
448       "snip($data, $maxlen)"
449           Format the data string in $data so that it's only (roughly) $maxlen
450           characters long and only contains printable characters.
451
452           If $data is longer than $maxlen, it will be formatted like
453
454               (22)[abcdef[snip=11]stuvw]
455
456           indicating the length of the original string, the beginning, the
457           end, and the number of 'snipped' characters.
458
459           If $data is shorter than $maxlen, it will be returned unmodified
460           (except for unprintable characters replaced, see below).
461
462           If $data contains unprintable character's they are replaced by "."
463           (the dot).
464
465       "password_read($prompt, $opts)"
466           Reads in a password to be typed in by the user in noecho mode.  A
467           call to password_read("password: ") results in
468
469               password: ***** (stars aren't actually displayed)
470
471           This function will switch the terminal back into normal mode after
472           the user hits the 'Return' key.
473
474           If the optional $opts hash has "{ tty => 1 }" set, then the prompt
475           will be redirected to the console instead of STDOUT.
476
477       "nice_time($time)"
478           Format the time in a human-readable way, less wasteful than the
479           'scalar localtime' formatting.
480
481               print nice_time(), "\n";
482                 # 2007/04/01 10:51:24
483
484           It uses the system time by default, but it can also accept epoch
485           seconds:
486
487               print nice_time(1170000000), "\n";
488                 # 2007/01/28 08:00:00
489
490           It uses localtime() under the hood, so the outcome of the above
491           will depend on your local time zone setting.
492
493       "def_or($foo, $default)"
494           Perl-5.9 added the //= construct, which helps assigning values to
495           undefined variables. Instead of writing
496
497               if(!defined $foo) {
498                   $foo = $default;
499               }
500
501           you can just write
502
503               $foo //= $default;
504
505           However, this is not available on older perl versions (although
506           there's source filter solutions). Often, people use
507
508               $foo ||= $default;
509
510           instead which is wrong if $foo contains a value that evaluates as
511           false.  So Sysadm::Install, the everything-and-the-kitchen-sink
512           under the CPAN modules, provides the function "def_or()" which can
513           be used like
514
515               def_or($foo, $default);
516
517           to accomplish the same as
518
519               $foo //= $default;
520
521           How does it work, how does $foo get a different value, although
522           it's apparently passed in by value? Modifying $_[0] within the
523           subroutine is an old Perl trick to do exactly that.
524
525       "is_utf8_data($data)"
526           Check if the given string has the utf8 flag turned on. Works just
527           like Encode.pm's is_utf8() function, except that it silently
528           returns a false if Encode isn't available, for example when an
529           ancient perl without proper utf8 support is used.
530
531       "utf8_check($data)"
532           Check if we're using a perl with proper utf8 support, by verifying
533           the Encode.pm module is available for loading.
534
535       "home_dir()"
536           Return the path to the home directory of the current user.
537

AUTHOR

539       Mike Schilli, <m@perlmeister.com>
540
542       Copyright (C) 2004-2007 by Mike Schilli
543
544       This library is free software; you can redistribute it and/or modify it
545       under the same terms as Perl itself, either Perl version 5.8.3 or, at
546       your option, any later version of Perl 5 you may have available.
547
548
549
550perl v5.36.0                      2022-07-22                Sysadm::Install(3)
Impressum