1Sysadm::Install(3) User Contributed Perl Documentation Sysadm::Install(3)
2
3
4
6 Sysadm::Install - Typical installation tasks for system administrators
7
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
33 Have you ever wished for your installation shell scripts to run
34 reproducably, 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()" immeditatly 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)"
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 "ask($prompt, $default)"
109 Ask the user to either hit Enter and select the displayed default
110 or to type in another string.
111
112 "mkd($dir)"
113 Create a directory of arbitrary depth, just like
114 "File::Path::mkpath".
115
116 "rmf($dir)"
117 Delete a directory and all of its descendents, just like "rm -rf"
118 in the shell.
119
120 "cd($dir)"
121 chdir to the given directory. If you don't want to have cd() modify
122 the internal directory stack (used for subsequent cdback() calls),
123 set the stack_update parameter to a false value:
124
125 cd($dir, {stack_update => 0});
126
127 "cdback()"
128 chdir back to the last directory before a previous "cd".
129
130 "make()"
131 Call "make" in the shell.
132
133 "pie($coderef, $filename, ...)"
134 Simulate "perl -pie 'do something' file". Edits files in-place.
135 Expects a reference to a subroutine as its first argument. It will
136 read out the file $filename line by line and calls the subroutine
137 setting a localized $_ to the current line. The return value of the
138 subroutine will replace the previous value of the line.
139
140 Example:
141
142 # Replace all 'foo's by 'bar' in test.dat
143 pie(sub { s/foo/bar/g; $_; }, "test.dat");
144
145 Works with one or more file names.
146
147 If the files are known to contain UTF-8 encoded data, and you want
148 it to be read/written as a Unicode strings, use the "utf8" option:
149
150 pie(sub { s/foo/bar/g; $_; }, "test.dat", { utf8 => 1 });
151
152 "plough($coderef, $filename, ...)"
153 Simulate "perl -ne 'do something' file". Iterates over all lines of
154 all input files and calls the subroutine provided as the first
155 argument.
156
157 Example:
158
159 # Print all lines containing 'foobar'
160 plough(sub { print if /foobar/ }, "test.dat");
161
162 Works with one or more file names.
163
164 If the files are known to contain UTF-8 encoded data, and you want
165 it to be read into Unicode strings, use the "utf8" option:
166
167 plough(sub { print if /foobar/ }, "test.dat", { utf8 => 1 });
168
169 "my $data = slurp($file, $options)"
170 Slurps in the file and returns a scalar with the file's content. If
171 called without argument, data is slurped from STDIN or from any
172 files provided on the command line (like <> operates).
173
174 If the file is known to contain UTF-8 encoded data and you want to
175 read it in as a Unicode string, use the "utf8" option:
176
177 my $unicode_string = slurp( $file, {utf8 => 1} );
178
179 "blurt($data, $file, $append)"
180 Opens a new file, prints the data in $data to it and closes the
181 file. If $append is set to a true value, data will be appended to
182 the file. Default is false, existing files will be overwritten.
183
184 If the string is a Unicode string, use the "utf8" option:
185
186 blurt( $unicode_string, $file, {utf8 => 1} );
187
188 "blurt_atomic($data, $file, $options)"
189 Write the data in $data to a file $file, guaranteeing that the
190 operation will either complete fully or not at all. This is
191 accomplished by first writing to a temporary file which is then
192 rename()ed to the target file.
193
194 Unlike in "blurt", there is no $append mode in "blurt_atomic".
195
196 If the string is a Unicode string, use the "utf8" option:
197
198 blurt_atomic( $unicode_string, $file, {utf8 => 1} );
199
200 "($stdout, $stderr, $exit_code) = tap($cmd, @args)"
201 Run a command $cmd in the shell, and pass it @args as args.
202 Capture STDOUT and STDERR, and return them as strings. If
203 $exit_code is 0, the command succeeded. If it is different, the
204 command failed and $exit_code holds its exit code.
205
206 Please note that "tap()" is limited to single shell commands, it
207 won't work with output redirectors ("ls >/tmp/foo" 2>&1).
208
209 In default mode, "tap()" will concatenate the command and args
210 given and create a shell command line by redirecting STDERR to a
211 temporary file. "tap("ls", "/tmp")", for example, will result in
212
213 'ls' '/tmp' 2>/tmp/sometempfile |
214
215 Note that all commands are protected by single quotes to make sure
216 arguments containing spaces are processed as singles, and no
217 globbing happens on wildcards. Arguments containing single quotes
218 or backslashes are escaped properly.
219
220 If quoting is undesirable, "tap()" accepts an option hash as its
221 first parameter,
222
223 tap({no_quotes => 1}, "ls", "/tmp/*");
224
225 which will suppress any quoting:
226
227 ls /tmp/* 2>/tmp/sometempfile |
228
229 Or, if you prefer double quotes, use
230
231 tap({double_quotes => 1}, "ls", "/tmp/$VAR");
232
233 wrapping all args so that shell variables are interpolated
234 properly:
235
236 "ls" "/tmp/$VAR" 2>/tmp/sometempfile |
237
238 "$quoted_string = qquote($string, [$metachars])"
239 Put a string in double quotes and escape all sensitive characters
240 so there's no unwanted interpolation. E.g., if you have something
241 like
242
243 print "foo!\n";
244
245 and want to put it into a double-quoted string, it will look like
246
247 "print \"foo!\\n\""
248
249 Sometimes, not only backslashes and double quotes need to be
250 escaped, but also the target environment's meta chars. A string
251 containing
252
253 print "$<\n";
254
255 needs to have the '$' escaped like
256
257 "print \"\$<\\n\";"
258
259 if you want to reuse it later in a shell context:
260
261 $ perl -le "print \"\$<\\n\";"
262 1212
263
264 "qquote()" supports escaping these extra characters with its
265 second, optional argument, consisting of a string listing all
266 escapable characters:
267
268 my $script = 'print "$< rocks!\\n";';
269 my $escaped = qquote($script, '!$'); # Escape for shell use
270 system("perl -e $escaped");
271
272 => 1212 rocks!
273
274 And there's a shortcut for shells: By specifying ':shell' as the
275 metacharacters string, qquote() will actually use '!$`'.
276
277 For example, if you wanted to run the perl code
278
279 print "foobar\n";
280
281 via
282
283 perl -e ...
284
285 on a box via ssh, you would use
286
287 use Sysadm::Install qw(qquote);
288
289 my $cmd = 'print "foobar!\n"';
290 $cmd = "perl -e " . qquote($cmd, ':shell');
291 $cmd = "ssh somehost " . qquote($cmd, ':shell');
292
293 print "$cmd\n";
294 system($cmd);
295
296 and get
297
298 ssh somehost "perl -e \"print \\\"foobar\\\!\\\\n\\\"\""
299
300 which runs on "somehost" without hickup and prints "foobar!".
301
302 Sysadm::Install comes with a script "one-liner" (installed in bin),
303 which takes arbitrary perl code on STDIN and transforms it into a
304 one-liner:
305
306 $ one-liner
307 Type perl code, terminate by CTRL-D
308 print "hello\n";
309 print "world\n";
310 ^D
311 perl -e "print \"hello\\n\"; print \"world\\n\"; "
312
313 "$quoted_string = quote($string, [$metachars])"
314 Similar to "qquote()", just puts a string in single quotes and
315 escapes what needs to be escaped.
316
317 Note that shells typically don't support escaped single quotes
318 within single quotes, which means that
319
320 $ echo 'foo\'bar'
321 >
322
323 is invalid and the shell waits until it finds a closing quote.
324 Instead, there is an evil trick which gives the desired result:
325
326 $ echo 'foo'\''bar' # foo, single quote, \, 2 x single quote, bar
327 foo'bar
328
329 It uses the fact that shells interpret back-to-back strings as one.
330 The construct above consists of three back-to-back strings:
331
332 (1) 'foo'
333 (2) '
334 (3) 'bar'
335
336 which all get concatenated to a single
337
338 foo'bar
339
340 If you call "quote()" with $metachars set to ":shell", it will
341 perform that magic behind the scenes:
342
343 print quote("foo'bar");
344 # prints: 'foo'\''bar'
345
346 "perm_cp($src, $dst, ...)"
347 Read the $src file's user permissions and modify all $dst files to
348 reflect the same permissions.
349
350 "$perms = perm_get($filename)"
351 Read the $filename's user permissions and owner/group. Returns an
352 array ref to be used later when calling "perm_set($filename,
353 $perms)".
354
355 "perm_set($filename, $perms)"
356 Set file permissions and owner of $filename according to $perms,
357 which was previously acquired by calling "perm_get($filename)".
358
359 "sysrun($cmd)"
360 Run a shell command via "system()" and die() if it fails. Also
361 works with a list of arguments, which are then interpreted as
362 program name plus arguments, just like "system()" does it.
363
364 "hammer($cmd, $arg, ...)"
365 Run a command in the shell and simulate a user hammering the ENTER
366 key to accept defaults on prompts.
367
368 "say($text, ...)"
369 Alias for "print ..., "\n"", just like Perl6 is going to provide
370 it.
371
372 "sudo_me()"
373 Check if the current script is running as root. If yes, continue.
374 If not, restart the current script with all command line arguments
375 is restarted under sudo:
376
377 sudo scriptname args ...
378
379 Make sure to call this before any @ARGV-modifying functions like
380 "getopts()" have kicked in.
381
382 "bin_find($program)"
383 Search all directories in $PATH (the ENV variable) for an
384 executable named $program and return the full path of the first
385 hit. Returns "undef" if the program can't be found.
386
387 "fs_read_open($dir)"
388 Opens a file handle to read the output of the following process:
389
390 cd $dir; find ./ -xdev -print0 | cpio -o0 |
391
392 This can be used to capture a file system structure.
393
394 "fs_write_open($dir)"
395 Opens a file handle to write to a
396
397 | (cd $dir; cpio -i0)
398
399 process to restore a file system structure. To be used in
400 conjunction with fs_read_open.
401
402 "pipe_copy($in, $out, [$bufsize])"
403 Reads from $in and writes to $out, using sysread and syswrite. The
404 buffer size used defaults to 4096, but can be set explicitely.
405
406 "snip($data, $maxlen)"
407 Format the data string in $data so that it's only (roughly) $maxlen
408 characters long and only contains printable characters.
409
410 If $data contains unprintable character's they are replaced by "."
411 (the dot). If $data is longer than $maxlen, it will be formatted
412 like
413
414 (22)[abcdef[snip=11]stuvw]
415
416 indicating the length of the original string, the beginning, the
417 end, and the number of 'snipped' characters.
418
419 "password_read($prompt)"
420 Reads in a password to be typed in by the user in noecho mode. A
421 call to password_read("password: ") results in
422
423 password: ***** (stars aren't actually displayed)
424
425 This function will switch the terminal back into normal mode after
426 the user hits the 'Return' key.
427
428 "nice_time($time)"
429 Format the time in a human-readable way, less wasteful than the
430 'scalar localtime' formatting.
431
432 print nice_time(), "\n";
433 # 2007/04/01 10:51:24
434
435 It uses the system time by default, but it can also accept epoch
436 seconds:
437
438 print nice_time(1170000000), "\n";
439 # 2007/01/28 08:00:00
440
441 It uses localtime() under the hood, so the outcome of the above
442 will depend on your local time zone setting.
443
444 "def_or($foo, $default)"
445 Perl-5.9 added the //= construct, which helps assigning values to
446 undefined variables. Instead of writing
447
448 if(!defined $foo) {
449 $foo = $default;
450 }
451
452 you can just write
453
454 $foo //= $default;
455
456 However, this is not available on older perl versions (although
457 there's source filter solutions). Often, people use
458
459 $foo ||= $default;
460
461 instead which is wrong if $foo contains a value that evaluates as
462 false. So Sysadm::Install, the everything-and-the-kitchen-sink
463 under the CPAN modules, provides the function "def_or()" which can
464 be used like
465
466 def_or($foo, $default);
467
468 to accomplish the same as
469
470 $foo //= $default;
471
472 How does it work, how does $foo get a different value, although
473 it's apparently passed in by value? Modifying $_[0] within the
474 subroutine is an old Perl trick to do exactly that.
475
476 "is_utf8_data($data)"
477 Check if the given string has the utf8 flag turned on. Works just
478 like Encode.pm's is_utf8() function, except that it silently
479 returns a false if Encode isn't available, for example when an
480 ancient perl without proper utf8 support is used.
481
482 "utf8_check($data)"
483 Check if we're using a perl with proper utf8 support, by verifying
484 the Encode.pm module is available for loading.
485
487 Mike Schilli, <m@perlmeister.com>
488
490 Copyright (C) 2004-2007 by Mike Schilli
491
492 This library is free software; you can redistribute it and/or modify it
493 under the same terms as Perl itself, either Perl version 5.8.3 or, at
494 your option, any later version of Perl 5 you may have available.
495
496
497
498perl v5.12.0 2010-04-13 Sysadm::Install(3)