27
The Bash: Defensive Scripting The Bash: Defensive Scripting 1 Dienstag, 16. August 11

The bash – defensive scripting

Embed Size (px)

DESCRIPTION

Fairly basic introduction to some principles and techniques for creating safe, fault-tolerant unix scripts using the Bash environment.

Citation preview

Page 1: The bash – defensive scripting

The Bash: Defensive Scripting

The Bash: Defensive Scripting

1

Dienstag, 16. August 11

Page 2: The bash – defensive scripting

The Bash: Defensive Scripting

UnixInterfacesRe-useDefensive ProgrammingReadings

2

Dienstag, 16. August 11

Page 3: The bash – defensive scripting

The Bash: Defensive Scripting

Unix• Be forgiving in what you accept, but strict in what you emit

• If you must fail, do so early and noisily

• One tool for each task• Human-readable data and protocols• Do the simplest thing that will do

3

Dienstag, 16. August 11

Page 4: The bash – defensive scripting

The Bash: Defensive Scripting

Unix: The Unix ToolboxGet familiar with cat, cut, tee, uniq, sort, head, tail, but also grep, sed, diff, find and possibly even awk. They will save you a whole lot of work.For more inspiration: ls /usr/binExtend your Unix Toolbox

4

Dienstag, 16. August 11

Page 5: The bash – defensive scripting

The Bash: Defensive Scripting

Interfaces• stdin, stdout, stderr, exit code• Favour plain text• Treat comments as comments• Filter, Source, Sink, Cantrip, Compiler

5

Dienstag, 16. August 11

Page 6: The bash – defensive scripting

The Bash: Defensive Scripting

Interfaces: FilterRead from stdin, write to stdoutPerfect for pipesExample: cut

6

Dienstag, 16. August 11

Page 7: The bash – defensive scripting

The Bash: Defensive Scripting

Interfaces: SourceRead from file, write to stdoutInterface to outer world, beginning of a pipe sequenceExample: cat

7

Dienstag, 16. August 11

Page 8: The bash – defensive scripting

The Bash: Defensive Scripting

Interfaces: SinkRead from stdin, write to fileInterface to outer world, end of a pipe sequenceExample: >

8

Dienstag, 16. August 11

Page 9: The bash – defensive scripting

The Bash: Defensive Scripting

Interfaces: CantripDo sth. and return nothing but a status code (or errors)This is super scriptableExample: rm

9

Dienstag, 16. August 11

Page 10: The bash – defensive scripting

The Bash: Defensive Scripting

Interfaces: CompilerRead from file, write to another fileExample: tar

10

Dienstag, 16. August 11

Page 11: The bash – defensive scripting

The Bash: Defensive Scripting

Re-use• Functions• Wrappers• $() (aka ``)• source (aka ‘.’)

11

Dienstag, 16. August 11

Page 12: The bash – defensive scripting

The Bash: Defensive Scripting

Re-use: FunctionsWill behave like a script on its ownfunction log () { echo “$(date) ERR $@” >&2}log “Cannot connect”# Do 4 Aug 2011 10:38:58 CEST ERR Cannot connect

12

Dienstag, 16. August 11

Page 13: The bash – defensive scripting

The Bash: Defensive Scripting

Re-use: Wrappers#!/bin/bash# file mcd -- make a dir if# necessary and cd to ittest -n “$1” || exit 1newdir=”$1”test -d $newdir || mkdir $newdircd $newdir

13

Dienstag, 16. August 11

Page 14: The bash – defensive scripting

The Bash: Defensive Scripting

Re-use: $()More readable than `backticks`myfiles=$(ls $HOME)

14

Dienstag, 16. August 11

Page 15: The bash – defensive scripting

The Bash: Defensive Scripting

Re-use: sourceMore readable than “.”source $HOME/lib/basics.shsource /etc/conf/script.cnf

15

Dienstag, 16. August 11

Page 16: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming• test, test, test (for $?)• find• && and || (AND and OR)• trap• log, stderr• --help, --version, usage()• Use full path names

16

Dienstag, 16. August 11

Page 17: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: testtest -r “$sourcefile”test -d “$destdir”test -x “$script”test -w “$destfile”test -n “$variable”test -z “$nothing”

17

Dienstag, 16. August 11

Page 18: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: testtest -r “$sourcefile”if [[ $? = 0 ]]; then echo “yes, it’s readable”else echo “cannot read $sourcefile”fi

18

Dienstag, 16. August 11

Page 19: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: && and ||test -r “$sourcefile” || exit 1

19

Dienstag, 16. August 11

Page 20: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: && and ||test -r “$sourcefile” || { echo “Cannot read source file” >&2 exit 1}

20

Dienstag, 16. August 11

Page 21: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: && and ||test -r “$sourcefile” && { cat -n “$sourcefile”} || { echo “Cannot read source file” >&2 exit 1}

21

Dienstag, 16. August 11

Page 22: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: findDon’t rely on a file being in some exact place. If it needs to be, tell the user.find Syntax is a bit peculiar.find $install_dir -name “*README*” -type f -exec mv {} $install_dir/docs/ \;

22

Dienstag, 16. August 11

Page 23: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: traptrap “/bin/rm -f $tmpf; exit” EXITtrap “source $config” SIGHUP

23

Dienstag, 16. August 11

Page 24: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: LogsWrite status to stderr. stderr is not for *errors* only, but for all kind of metainformationUse syslog/logger or your own logging function

24

function log () { msg=“$(date) ERR $@” test -w $LOGF && echo $msg > $LOGF echo $msg >&2}

Dienstag, 16. August 11

Page 25: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: --help, --version• Simplify the use of your program by providing --help and --version

• On error print a usage message

25

Dienstag, 16. August 11

Page 26: The bash – defensive scripting

The Bash: Defensive Scripting

Defensive Programming: use full path namesbase=$HOME/installsrcf=$base/source.txtdstf=$base/destination.txttest -r $srcf && cp -i $srcf $dstf

26

Dienstag, 16. August 11

Page 27: The bash – defensive scripting

The Bash: Defensive Scripting

Readings• Advanced Bash-Scripting Guide http://

tldp.org/LDP/abs/html/• The Art of Unix Programming (by Eric S.

Raymond; http://www.faqs.org/docs/artu/)• Wicked Cool Shell Scripts (No Starch Press)• Patrick Jezek: Bash Techtalk (08/2010)

http://slides.liip.ch/shell_scripting/index.html

27

Dienstag, 16. August 11