1 Unix shell scripting with ksh/bash
3 Course Handout: (last update 22 March 2012)
5 These notes may be found at http://www.dartmouth.edu/~rc/classes/ksh. The
6 online version has many links to additional information and may be more up
7 to date than the printed notes
9 ----------------------------------------------------------------------
11 UNIX shell scripting with ksh/bash
13 The goals of this class are to enable you to:
15 o Learn what kinds of problems are suited to shell scripts
16 o Review the most commonly used Unix commands that are useful in shell
18 o Write simple shell scripts using the Bourne, Korn or Bash shells
19 These notes are intended for use in a 2-part class, total duration 3
23 It is assumed that you already know how to:
24 * log in and get a command line window (any shell)
25 * run basic commands, navigate directories
26 * use simple I/O redirection and pipes
27 * use a text editor (any one)
28 * look up details of command usage in man pages
29 Example commands are shown like this. Many commands are shown with links
30 to their full man pages (sh)
31 Output from commands is shown like this; optional items are [ in brackets
34 Some descriptions in these notes have more detail available, and are
37 More details of this item would appear here. The printed notes include
38 all of the additional information
40 ----------------------------------------------------------------------
42 Permission is granted to download and use these notes and example scripts,
43 as long as all copyright notices are kept intact. Some of the examples are
44 taken from texts or online resources which have granted permission to
47 These notes are updated from time to time. The "development" set of
48 notes are http://northstar-www.dartmouth.edu/~richard/classes/ksh
51 Richard Brittain, Dartmouth College Computing Services.
52 © 2003,2004,2010 Dartmouth College.
53 Comments and questions, contact Richard.Brittain @ dartmouth.edu
55 Best viewed with ANY browser Powered by Vi
57 ----------------------------------------------------------------------
61 1. What is a shell script
62 2. Why use shell scripts
65 5. Other scripting languages
73 13. Command substitution
74 14. I/O redirection and pipelines
77 17. Conditional Tests (contd.)
79 19. Flow control (contd.)
80 20. Conditional test examples
82 22. Manipulating Variables
92 32. Common external commands
97 What is a Shell Script
99 * A text file containing commands which could have been typed directly
102 There is no difference in syntax between interactive command line
103 use and placing the commands in a file. Some commands are only
104 useful when used interactively (e.g. command line history recall)
105 and other commands are too complex to use interactively.
107 * The shell itself has limited capabilities -- the power comes from
108 using it as a "glue" language to combine the standard Unix utilities,
109 and custom software, to produce a tool more useful than the component
112 * Any shell can be used for writing a shell script. To allow for this,
113 the first line of every script is:
114 #!/path/to/shell (e.g. #!/bin/ksh).
116 The #! characters tell the system to locate the following pathname,
117 start it up and feed it the rest of the file as input. Any program
118 which can read commands from a file can be started up this way, as
119 long as it recognizes the # comment convention. The program is
120 started, and then the script file is given to it as an argument.
121 Because of this, the script must be readable as well as executable.
122 Examples are perl, awk, tcl and python.
124 * Any file can be used as input to a shell by using the syntax:
127 * If the file is made executable using chmod, it becomes a new command
128 and available for use (subject to the usual $PATH search).
130 A shell script can be as simple as a sequence of commands that you type
131 regularly. By putting them into a script, you reduce them to a single
134 Example: ex0 display, text
143 Why use Shell Scripts
145 * Combine lengthy and repetitive sequences of commands into a single,
148 * Generalize a sequence of operations on one set of data, into a
149 procedure that can be applied to any similar set of data.
151 (e.g. apply the same analysis to every data file on a CD, without
152 needing to repeat the commands)
154 * Create new commands using combinations of utilities in ways the
155 original authors never thought of.
157 * Simple shell scripts might be written as shell aliases, but the script
158 can be made available to all users and all processes. Shell aliases
159 apply only to the current shell.
161 * Wrap programs over which you have no control inside an environment
162 that you can control.
164 e.g. set environment variables, switch to a special directory,
165 create or select a configuration file, redirect output, log usage,
166 and then run the program.
168 * Create customized datasets on the fly, and call applications (e.g.
169 matlab, sas, idl, gnuplot) to work on them, or create customized
170 application commands/procedures.
172 * Rapid prototyping (but avoid letting prototypes become production)
176 * System boot scripts (/etc/init.d)
178 * System administrators, for automating many aspects of computer
179 maintenance, user account creation etc.
181 * Application package installation tools
183 Other tools may create fancier installers (e.g. tcl/tk), but can not
184 be assumed to be installed already. Shell scripts are used because
185 they are very portable. Some software comes with a complete
186 installation of the tool it wants to use (tcl/tk/python) in order to
187 be self contained, but this leads to software bloat.
189 * Application startup scripts, especially unattended applications (e.g.
190 started from cron or at)
192 * Any user needing to automate the process of setting up and running
193 commercial applications, or their own code.
195 AUTOMATE, AUTOMATE, AUTOMATE
202 aka "Bourne" shell, written by Steve Bourne at AT&T Bell Labs for
203 Unix V7 (1979). Small, simple, and (originally) very few internal
204 commands, so it called external programs for even the simplest of
205 tasks. It is always available on everything that looks vaguely
209 The "C" shell. (Bill Joy, at Berkeley). Many things in common with
210 the Bourne shell, but many enhancements to improve interactive
211 use. The internal commands used only in scripts are very different
212 from "sh", and similar (by design) to the "C" language syntax.
215 The "TC" shell. Freely available and based on "csh". It has many
216 additional features to make interactive use more convenient.
218 We use it as the default interactive shell for new accounts on
219 all of our public systems.
220 Not many people write scripts in [t]csh. See Csh Programming
221 Considered Harmful by Tom Christiansen for a discussion of
222 problems with programming csh scripts.
225 The "Korn" shell, written by David Korn of AT&T Bell Labs (now
226 AT&T Research). Written as a major upgrade to "sh" and backwards
227 compatible with it, but has many internal commands for the most
228 frequently used functions. It also incorporates many of the
229 features from tcsh which enhance interactive use (command line
230 history recall etc.).
232 It was slow to gain acceptance because earlier versions were
233 encumbered by AT&T licensing. This shell is now freely available
234 on all systems, but sometimes not installed by default on "free"
235 Unix. There are two major versions. ksh88 was the version
236 incorporated into AT&T SVR4 Unix, and may still be installed by
237 some of the commercial Unix vendors. ksh93 added more features,
238 primarily for programming, and better POSIX compliance.
240 POSIX 1003.2 Shell Standard.
241 Standards committees worked over the Bourne shell and added many
242 features of the Korn shell (ksh88) and C shell to define a
243 standard set of features which all compliant shells must have.
245 On most systems, /bin/sh is now a POSIX compliant shell. Korn
246 shell and Bash are POSIX compliant, but have many features which
247 go beyond the standard. On Solaris, the POSIX/XPG4 commands
248 which differ slightly in behaviour from traditional SunOS
249 commands are located in /usr/xpg4/bin
252 The "Bourne again" shell. Written as part of the GNU/Linux Open
253 Source effort, and the default shell for Linux and Mac OS-X. It is
254 a functional clone of sh, with additional features to enhance
255 interactive use, add POSIX compliance, and partial ksh
259 A freeware functional clone of sh, with parts of ksh, bash and
260 full POSIX compliance, and many new interactive command-line
261 editing features. It was installed as the default shell on early
266 Comparison of shell features
268 All the shells just listed share some common features, and the major
269 differences in syntax generally only affect script writers. It is not
270 unusual to use one shell (e.g. tcsh) for interactive use, but another (sh
271 or ksh) for writing scripts.
273 Core Similarities (and recap of basic command line usage)
275 Each of these items is discussed in more detail later.
276 * Parse lines by whitespace, search for external commands using $PATH.
277 * Can run a shell script using shellname scriptfile, or run a single
278 command using shellname -c "command"
279 * Pass expanded command line arguments to programs; get exit status
281 * Pass environment variables to programs.
282 * Expand filename wildcards using []*?. Each shell has some additional
283 wildcard metacharacters, but these are common to all shells.
284 * Standard I/O redirection and piping with <,>,>>,|
285 * A few internal functions (cd)
286 * Backgrounding commands with &
287 * Quoting rules: "double quotes" protect most things, but allow $var
288 interpretation; 'single quotes' protect all metacharacters from
290 * Home directory expansion using ~user (except for sh)
293 * Command substitution using `command` (backtics)
294 * Expand variables using $varname syntax
295 * Conditional execution using && and ||
296 * Line continuation with "\"
298 Principal Differences
300 between sh (+derivitives), and csh (+derivitives).
301 * Syntax of all the flow control constructs and conditional tests.
302 * Syntax for string manipulation inside of scripts
303 * Syntax for arithmetic manipulation inside of scripts
304 * Syntax for setting local variables (used only in the script) and
305 environment variables (which are passed to child processes). setenv vs
307 * Syntax for redirecting I/O streams other than stdin/stdout
308 * Login startup files (.cshrc and .login, vs .profile) and default
310 * Reading other shell scripts into the current shell (source filename,
312 * Handling of signals (interrupts)
316 Other Scripting Languages
318 There are many other programs which read a file of commands and carry out
319 a sequence of actions. The "#!/path/to/program" convention allows any of
320 them to be used as a scripting language to create new commands. Some are
321 highly specialized, and some are much more efficient than the equivalent
322 shell scripts at certain tasks. There is never only one way to perform a
323 function, and often the choice comes down to factors like:
324 * what is installed already - many other scripting languages are not
326 * what similar code already exists
327 * what you are most familiar with and can use most efficiently. Your
328 time is always more expensive than computer cycles.
329 Some major players (all of these are freely available) in the general
330 purpose scripting languages are:
333 A pattern matching and data (text and numeric) manipulation tool.
334 Predates perl. Installed on all Unix systems. Often used in
335 combination with shell scripts.
339 The most used scripting language for Web CGI applications and system
340 administration tasks. Perl is harder to learn, and is uusually
341 installed by default now. It is more efficient and has an enormous
342 library of functions available. You could use Perl for almost all
343 scripting tasks, but the syntax is very different to the shell
348 An object-oriented scripting language. Commonly installed by default
353 Tool Command Language. Another general purpose scripting language.
354 The "tk" component is a scripted interface to standard X-windows
355 graphical components, so the combination is often used to create
356 graphical user interfaces.
358 Ksh93 can be extended by linking to shared libraries providing
359 additional internal commands. One example of an extended shell is
360 tksh which incorporates Tcl/Tk with ksh and allows generation of
361 scripts using both languages. It can be used for prototyping GUI
368 Ksh and bash are both supersets of sh. For maximum portability, even to
369 very old computers, you should stick to the commands found in sh. Where
370 possible, ksh or bash-specific features will be noted in the following
371 pages. In general, the newer shells run a little faster and scripts are
372 often more readable because logic can be expressed more cleanly user the
373 newer syntax. Many commands and conditional tests are now internal.
375 The philosophy of separate Unix tools each performing a single operation
376 was followed closely by the designers of the original shell, so it had
377 very few internal commands and used external tools for very trivial
378 operations (like echo and [). Ksh and bash internally performs many of
379 the basic string and numeric manipulations and conditional tests.
380 Occasional problems arise because the internal versions of some commands
381 like echo are not fully compatible with the external utility they
384 The action taken every time a shell needs to run an external program is
385 to locate the program (via $PATH), fork(), which creates a second copy
386 of the shell, adjust the standard input/output for the external program,
387 and exec(), which replaces the second shell with the external program.
388 This process is computationally expensive (relatively), so when the
389 script does something trivial many times over in a loop, it saves a lot
390 of time if the function is handled internally.
392 If you follow textbooks on Bourne shell programming, all of the advice
393 should apply no matter which of the Bourne-derived shells you use.
394 Unfortunately, many vendors have added features over the years and
395 achieving complete portability can be a challenge. Explicitly writing for
396 ksh (or bash) and insisting on that shell being installed, can often be
399 The sh and ksh man pages use the term special command for the internal
400 commands - handled by the shell itself.
404 Basic sh script syntax
406 The most basic shell script is a list of commands exactly as could be
407 typed interactively, prefaced by the #! magic header. All the parsing
408 rules, filename wildcards, $PATH searches etc., which were summarized
412 # as the first non-whitespace character on a line
413 flags the line as a comment, and the rest of the line is
414 completely ignored. Use comments liberally in your scripts, as in
415 all other forms of programming.
417 \ as the last character on a line
418 causes the following line to be logically joined before
419 interpretation. This allows single very long commands to be
420 entered in the script in a more readable fashion. You can continue
421 the line as many times as needed.
423 This is actually just a particular instance of \ being to
424 escape, or remove the special meaning from, the following
427 ; as a separator between words on a line
428 is interpreted as a newline. It allows you to put multiple
429 commands on a single line. There are few occasions when you must
430 do this, but often it is used to improve the layout of compound
433 Example: ex1 display, text
436 2: # For the purposes of display, parts of the script have
437 3: # been rendered in glorious technicolor.
438 4: ## Some comments are bold to flag special sections
440 6: # Line numbers on the left are not part of the script.
441 7: # They are just added to the HTML for reference.
443 9: # Built-in commands and keywords (e.g. print) are in blue
444 10: # Command substitutions are purple. Variables are black
445 11: print "Disk usage summary for $USER on `date`"
447 13: # Everything else is red - mostly that is external
448 14: # commands, and the arguments to all of the commands.
449 15: print These are my files # end of line comment for print
450 16: # List the files in columns
452 18: # Summarize the disk usage
454 20: print Disk space usage
460 Every command (program) has a value or exit status which it returns to the
461 calling program. This is separate from any output generated. The exit
462 status of a shell script can be explicitly set using exit N, or it
463 defaults to the value of the last command run.
465 The exit status is an integer 0-255. Conventionally 0=success and any
466 other value indicates a problem. Think of it as only one way for
467 everything to work, but many possible ways to fail. If the command was
468 terminated by a signal, the value is 128 plus the signal value.
474 The following characters are interpreted by the shell as filename
475 wildcards, and any word containing them is replaced by a sorted list of
476 all the matching files.
478 Wildcards may be used in the directory parts of a pathname as well as
479 the filename part. If no files match the wildcard, it is left unchanged.
480 Wildcards are not full regular expressions. Sed, grep, awk etc. work
481 with more flexible (and more complex) string matching operators.
484 Match zero or more characters.
487 Match any single character
490 Match any single character from the bracketed set. A range of
491 characters can be specified with [ - ]
494 Match any single character NOT in the bracketed set.
496 * An initial "." in a filename does not match a wildcard unless
497 explicitly given in the pattern. In this sense filenames starting with
498 "." are hidden. A "." elsewhere in the filename is not special.
500 * Pattern operators can be combined
503 chapter[1-5].* could match chapter1.tex, chapter4.tex, chapter5.tex.old.
504 It would not match chapter10.tex or chapter1
510 Scripts are not very useful if all the commands and options and filenames
511 are explicitly coded. By using variables, you can make a script generic
512 and apply it to different situations. Variable names consist of letters,
513 numbers and underscores ([a-zA-Z0-9_], cannot start with a number, and are
514 case sensitive. Several special variables (always uppercase names) are
515 used by the system -- resetting these may cause unexpected behaviour. Some
516 special variables may be read-only. Using lowercase names for your own
519 Setting and exporting variables
522 Creates (if it didn't exist) a variable named "srcfile" and sets
523 it to the value "dataset1". If the variable already existed, it is
524 overwritten. Variables are treated as text strings, unless the
525 context implies a numeric interpretation. You can make a variable
526 always be treated as a number. Note there must be no spaces around
530 Display all the variables currently set in the shell
533 Remove the variable "srcfile"
536 Give the variable a null value, (not the same as removing it).
539 Added srcfile to the list of variables which will be made
540 available to external program through the environment. If you
541 don't do this, the variable is local to this shell instance.
544 List all the variables currently being exported - this is the
545 environment which will be passed to external programs.
550 Prefacing the variable name with $ causes the value of the
551 variable to be substituted in place of the name.
554 If the variable is not surrounded by whitespace (or other
555 characters that can't be in a name), the name must be surrounded
556 by "{}" braces so that the shell knows what characters you intend
557 to be part of the name.
562 # Tries to find $datafile_part1, which doesn't exist
563 echo $datafile_part1.sas
564 # This is what we intended
565 echo ${datafile}_part1.sas
567 Conditional modifiers
569 There are various ways to conditionally use a variable in a command.
572 Substitute the value of $datafile, if it has been defined,
573 otherwise use the string "default". This is an easy way to allow
574 for optional variables, and have sensible defaults if they haven't
575 been set. If datafile was undefined, it remains so.
578 Similar to the above, except if datafile has not been defined, set
579 it to the string "default".
582 If variable datafile has been defined, use the string "default",
583 otherwise use null. In this case the actual value $datafile is not
586 ${datafile?"error message"}
587 Substitute the value of $datafile, if it has been defined,
588 otherwise display datafile: error message. This is used for
589 diagnostics when a variable should have been set and there is no
590 sensible default value to use.
592 Placing a colon (:) before the operator character in these
593 constructs has the effect of counting a null value the same as
594 an undefined variable. Variables may be given a null value by
595 setting them to an empty string, e.g. datafile= .
596 Example: echo ${datafile:-mydata.dat}
597 Echo the value of variable datafile if it has been set and is
598 non-null, otherwise echo "mydata.dat".
600 Variable assignment command prefix
602 It is possible to export a variable just for the duration of a single
603 command using the syntax:
604 var=value command args
608 Preset Shell Variables
610 Several special variables are used by the system -- you can use these, but
611 may not be able to change them. The special variables use uppercase names,
612 or punctuation characters. Some variables are set by the login process and
613 inherited by the shell (e.g. $USER), while others are used only by the
615 Try running set or env
616 These are some of the more commonly used ones:
621 Preset to the currently logged-in username.
624 The list of directories that will be searched for external
625 commands. You can change this in a script to make sure you get the
626 programs you intend, and don't accidentally get other versions
627 which might have been installed.
630 The terminal type in which the shell session is currently
631 executing. Usually "xterm" or "vt100". Many programs need to know
632 this to figure out what special character sequences to send to
633 achieve special effects.
636 If set, this contains the name of the program which the user
637 prefers to use for text file viewing. Usually set to "more" or
638 "less" or something similar. Many programs which need to present
639 multipage information to the user will respect this setting (e.g.
640 man). This isn't actually used by the shell itself, but shell
641 scripts should honour it if they need to page output to the user.
644 If set, this contains the name of the program which the user
645 prefers to use for text file editing. A program which needs to
646 have the user manually edit a file might choose to start up this
647 program instead of some built-in default (e.g. "crontab -e". This
648 also determines the default command-line-editing behaviour in
651 Shell internal settings
654 Always set the current working directory (readonly)
657 The previous directory (before the most recent cd command).
658 However, changing directories in a script is often dangerous.
661 Set to the exit status of the last command run, so you can test
662 success or failure. Every command resets this so it must be saved
663 immediately if you want to use it later.
666 Set to the currently set options flags.
669 Internal Field Separators: the set of characters (normally space
670 and tab) which are used to parse a command line into separate
671 arguments. This may be set by the user for special purposes, but
672 things get very confusing if it isn't changed back.
677 Set to the process ID of the current shell - useful in making
678 unique temporary files, e.g. /tmp/$0.$$
681 Set to the process ID of the parent process of this shell - useful
682 for discovering how the script was called.
685 Set to the process ID of the last command started in background -
686 useful for checking on background processes.
688 ksh/bash additional features
691 Integer number of seconds since this shell was started. Can be
692 used for timing commands.
695 Every time it is valuated, $RANDOM returns a random integer in the
696 range 0-32k. RANDOM may be set to "seed" the random number
700 Always evaluates to the current line number of the script being
701 executed - useful for debugging.
705 Command Line (positional) arguments
707 To customize the behaviour of a script at run time, you can give it any
708 number of arguments on the command line.
710 These are often filenames, but can be interpreted by the script in any
711 way. Options are often specified using the "-flag" convention used by
712 most Unix programs, and a ksh command getopts is available to help parse
715 The shell expands wildcards and makes variable and command substitutions
716 as normal, then parses the resulting words by whitespace (actually special
717 variable $IFS), and places the resulting text strings into the positional
718 variables as follows:
721 The first 9 arguments are made available directly as $1-$9. To
722 access more than 9, use shift, or $*, $@. The variable $0 contains
723 the name of the script itself.
726 Positional arguments greater than 9 are set by ksh and bash.
727 Remember to use braces to refer to them.
730 discard $1 and renumber all the other variables. "shift N" will
731 shift N arguments at once.
734 contains the number of arguments that were set (not including $0).
737 contains all of the arguments in a single string, with one space
741 similar to $*, but if used in quotes, it effectively quotes each
742 argument and keeps them separate. If any argument contains
743 whitespace, the distinction is important.
745 e.g. if the argument list is: a1 a2 "a3 which contains spaces" a4
746 then: $1=a1, $2=a2, $3=a3 which contains spaces, $4=a4
747 and: $*=a1 a2 a3 which contains spaces a4
748 and: "$@"="a1" "a2" "a3 which contains spaces" "a4"
750 Only using the form "$@" preserves quoted arguments. If the arguments are
751 being passed from the script directly to some other program, it may make a
752 big difference to the meaning.
754 Example: ex7 display, text
758 3: # Check positional argument handling
759 4: echo "Number of arguments: $#"
762 7: echo "Loop over \$*"
767 12: echo "Loop over \"\$@\""
768 13: for a in "$@"; do
772 Setting new positional arguments
774 The set command, followed by a set of arguments, creates a new set of
775 positional arguments. This is often used, assuming the original arguments
776 are no longer needed, to parse a set of words (possibly using different
777 field separators). Arguments may be reset any number of times.
779 Example: ex2 display, text
782 2: # Find an entry in the password file
783 3: pwent=`grep '^root:' /etc/passwd`
784 4: # Turn off globbing - passwd lines often contain '*'
786 6: # The "full name" and other comments are in
787 7: # field 5, colon delimited. Get this field using shell word splitting
788 8: OIFS=$IFS; IFS=: ; set $pwent; IFS=$OIFS
791 Example: pickrandom display, text
792 Selects a random file from a directory. Uses the ksh RANDOM feature.
796 3: # Select a random image from the background logo collection
797 4: # This could be used to configure a screen saver, for example.
799 6: # This works even if the filenames contain spaces.
801 8: # switch to the logos directory to avoid long paths
802 9: logos=/afs/northstar/common/usr/lib/X11/logos/backgrounds
805 12: # '*' is a filename wildcard to match all files in the current directory
808 15: # Use the syntax for arithmetic expressions. "%" is the modulo operator
809 16: # Shift arguments by a random number between 0 and the number of files
810 17: shift $(($RANDOM % $#))
812 19: # Output the resulting first argument
819 Startup options. ksh -options scriptname
822 echo line to stderr before executing it
825 read commands and check for syntax errors, but do not execute.
828 all variables are automatically exported
831 disable wildcard filename expansion (globbing)
834 Set an option within a shell script
837 contains the currently set option letters
839 There are many other options, not often needed. Options in ksh and bash
840 can also be set using long names (e.g. -o noglob instead of -f). Many
841 options are unique to ksh or bash.
850 A command (plus optional arguments) enclosed in backticks is
851 executed and the standard output of that command is substituted.
852 If the command produces multiline output, the newlines are
853 retained. If the resultant string is displayed, unquoted, using
854 echo, newlines and multiple spaces will be removed.
859 This syntax is functionally the same as backticks, but commands
860 can be more easily nested.
863 This is equivalent to `cat file`, but implemented internally for
866 Example: ex3 display, text
870 3: echo Today is `date`
873 6: echo The file $file has $(wc -l < $file) lines
875 8: hostname -s > myhostname
876 9: echo This system has host name $(<myhostname)
880 I/O redirection and pipelines
882 Any simple command (or shell function, or compound command) may have its
883 input and output redirected using the following operators. This is
884 performed by the shell before the command is run.
889 Standard ouput (file descriptor 1) is redirected to the named
890 file. The file is overwritten unless the noclobber option is set.
891 The file is created if it does not exist.
893 The special device file /dev/null can be used to explicitly
894 discard unwanted output. Reading from /dev/null results in an
898 Standard ouput is appended to the named file. The file is created
899 if it does not exist.
902 Output redirect, and override the noclobber option, if set.
907 Standard input (file descriptor 0) is redirected to the named
908 file. The file must already exist.
912 command | command [ | command ...]
913 Pipe multiple commands together. The standard output of the first
914 command becomes the standard input of the second command. All
915 commands run simultaneously, and data transfer happens via memory
916 buffers. This is one of the most powerful constructs in Unix.
917 Compound commands may also be used with pipes. Pipes play very
918 nicely with multiprocessor systems.
920 No more than one command in a pipeline should be interactive
921 (attempt to read from the terminal). This construct is much more
922 efficient than using temporary files, and most standard Unix
923 utilities are designed such that they work well in pipelines.
925 The exit status of a pipeline is the exit status of the last
926 command. In compound commands, a pipeline can be used anywhere a
927 simple command could be used.
933 Shell scripts can generate output directly or read input into variables
934 using the following commands:
939 Print arguments, separated by spaces, and terminated by a newline,
940 to stdout. Use quotes to preserve spacing. Echo also understands
941 C-like escape conventions.
943 Beware that the shell may process backslashes before echo sees
944 them (may need to double backslash). Internal in most shells,
945 but was originally external.
947 \b backspace \c print line without new-line (some
949 \f form-feed \n new-line
950 \r carriage return \t tab
951 \v vertical tab \\ backslash
953 \0n where n is the 8-bit character whose ASCII code is the 1-,
954 2- or 3-digit octal number representing that character.
960 Print arguments, separated by spaces, and terminated by a newline,
961 to stdout. Print observes the same escape conventions as echo.
967 raw mode - ignore \-escape conventions
970 raw mode - ignore \-escape conventions and -options
976 read a line from stdin, parsing by $IFS, and placing the words
977 into the named variables. Any left over words all go into the last
978 variable. A '\' as the last character on a line removes
979 significance of the newline, and input continues with the
983 raw mode - ignore \-escape conventions
985 Example: ex4a display, text
988 2: echo "Testing interactive user input: enter some keystrokes and press return"
990 4: echo "First word was \"$x\""
991 5: echo "Rest of the line (if any) was \"$more\""
995 Conditional tests for [...] and [[...]] commands
997 Most of the useful flow-control operators involve making some conditional
998 test and branching on the result (true/false). The test can be either the
999 test command, or its alias, [, or the ksh/bash built-in [[ ... ]] command,
1000 which has slightly different options, or it can be any command which
1001 returns a suitable exit status. Zero is taken to be "True", while any
1002 non-zero value is "False". Note that this is backwards from the C language
1008 True if file exists (can be of any type).
1011 True if file exists and is an ordinary file.
1014 True if file exists and is a directory.
1017 True if file exists and is readable
1018 Similarly, -w = writable, -x = executable, -L = is a symlink.
1021 True if file exists and has size greater than zero
1024 True if the open filedescriptor is associated with a terminal
1025 device. E.g. this is used to determine if standard output has been
1026 redirected to a file.
1028 Character string tests
1031 true if string has non-zero length
1034 true if string has zero length
1036 With [, the argument must be quoted, because if it is a variable
1037 that has a null value, the resulting expansion ( [ -z ] ) is a
1038 syntax error. An expansion resulting in "" counts as a null
1040 For [ only, a quoted string alone is equivalent to the -n test,
1041 e.g. [ "$var" ]. In older shells for which [ is an external
1042 program, the only way to test for a null string is:
1043 if [ "X$var" = "X" ]
1044 This is rarely needed now, but is still often found.
1047 True if $variable matches text.
1050 True if $variable comes before (lexically) text
1051 Similarly, > = comes after
1055 More conditional tests for [...] and [[...]] commands
1059 $variable -eq number
1060 True if $variable, interpreted as a number, is equal to number.
1062 $variable -ne number
1063 True if $variable, interpreted as a number, is not equal to
1065 Similarly, -lt = less than, -le = less than or equal, -gt =
1066 greater than, -ge = greater than or equal
1068 Additional tests for [[...]] (ksh and bash)
1071 True if $variable matches pattern. If pattern contains no
1072 wildcards, then this is just an exact text match. The same
1073 wildcards as used for filename matching are used.
1075 The pattern must not be quoted. Since [[...]] is internal to the
1076 shell, the pattern in this case is treated differently and not
1077 filename-expanded as an external command would require.
1080 True if file1 is newer than file2.
1081 Similarly -ot = older than
1084 true if file1 is effectively the same as file2, after following
1085 symlinks and hard links.
1087 Negating and Combining tests
1089 Tests may be negated by prepending the ! operator, and combined with
1090 boolean AND and OR operators using the syntax:
1092 conditional -a conditional, conditional -o conditional
1093 AND and OR syntax for test and [
1095 conditional && conditional, conditional || conditional
1096 AND and OR syntax for [[ ... ]]
1098 Parentheses may be inserted to resolve ambiguities or override the default
1099 operator precedence rules.
1103 if [[ -x /usr/local/bin/lserve && \
1104 -w /var/logs/lserve.log ]]; then
1105 /usr/local/bin/lserve >> /var/logs/lserve.log &
1108 pwent=`grep '^richard:' /etc/passwd`
1109 if [ -z "$pwent" ]; then
1110 echo richard not found
1115 Flow Control and Compound Commands
1117 A list in these descriptions is a simple command, or a pipeline. The value
1118 of the list is the value of the last simple command run in it.
1120 A list can also be a set of simple commands or pipelines separated by
1121 ";,&,&&,||,|&". For the compound commands which branch on the success or
1122 failure of some list, it is usually [ or [[, but can be anything.
1124 Conditional execution: if/else
1127 Execute the first list. If true (success), execute the second one.
1130 Execute the first list. If false (failure), execute the second
1135 mkdir tempdir && cp workfile tempdir
1137 sshd || echo "sshd failed to start"
1139 You can use both forms together (with care) - they are processed
1140 left to right, and && must come first.
1143 mkdir tempdir && cp workfile tempdir || \
1144 echo "Failed to create tempdir"
1146 if list; then list ; elif list; then list; else list; fi
1147 Execute the first list, and if true (success), execute the "then"
1148 list, otherwise execute the "else" list. The "elif" and "else"
1157 echo $myfile not readable
1160 Looping: 'while' and 'for' loops
1162 while list; do list; done
1164 until list; do list; done
1165 Execute the first list and if true (success), execute the second
1166 list. Repeat as long as the first list is true. The until form
1167 just negates the test.
1169 Example: ex4 display, text
1174 4: while [[ $count -lt $max ]]
1177 7: count=$((count + 1))
1179 9: echo "Value of count after loop is: $count"
1181 for identifier [ in words ]; do; list; done
1182 Set identifier in turn to each word in words and execute the list.
1183 Omitting the "in words" clause implies using $@, i.e. the
1184 identifier is set in turn to each positional argument.
1190 echo Processing $file
1193 As with most programming languages, there are often several ways to
1194 express the same action. Running a command and then explicitly examining
1195 $? can be used instead of some of the above.
1197 Compound commands can be thought of as running in an implicit subshell.
1198 They can have I/O redirection independant of the rest of the script.
1199 Setting of variables in a real subshell does not leave them set in the
1200 parent script. Setting variables in implicit subshells varies in behaviour
1201 among shells. Older sh could not set variables in an implicit subshell and
1202 then use them later, but current ksh can do this (mostly).
1204 Example: ex11 display, text
1205 Reading a file line by line. The book by Randal Michael contains 12
1206 example ways to read a file line by line, which vary tremendously in
1207 efficiency. This example shows the simplest and fastest way.
1211 3: # Demonstrate reading a file line-by-line, using I/O
1212 4: # redirection in a compound command
1213 5: # Also test variable setting inside an implicit subshell.
1214 6: # Test this under sh and ksh and compare the output.
1219 11: if [ -z "$1" ]; then
1220 12: echo "Usage: $0 filename"
1222 14: if [ -r $1 ]; then
1223 15: while read line; do
1229 21: echo "End value of \$line is $line"
1230 22: echo "End value of \$save is $save"
1234 Flow Control and Compound Commands (contd.)
1236 Case statement: pattern matching
1238 case word in pattern) list;; esac
1239 Compare word with each pattern) in turn, and executes the first
1240 list for which the word matches. The patterns follow the same
1241 rules as for filename wildcards.
1243 (ksh and bash only) A pattern-list is a list of one or more
1244 patterns separated from each other with a |. Composite patterns
1245 can be formed with one or more of the following:
1248 Optionally matches any one of the given patterns.
1251 Matches zero or more occurrences of the given
1255 Matches one or more occurrences of the given
1259 Matches exactly one of the given patterns.
1262 Matches anything, except one of the given patterns.
1268 echo Processing a .dat file
1271 echo Processing a .sas file
1274 # catch anything else that doesn't match patterns
1275 echo "Don't know how to deal with $filename"
1279 Miscellaneous flow control and subshells
1282 Break out of the current (or n'th) enclosing loop. Control jumps to
1283 the next statement after the loop
1286 Resume iteration of the current (or n'th) enclosing loop. Control
1287 jumps to the top of the loop, which generally causes re-evaluation of
1288 a while or processing the next element of a for.
1291 Read the contents of the named file into the current shell and
1292 execute as if in line. Uses $PATH to locate the file, and can be
1293 passed positional parameters. This is often used to read in shell
1294 functions that are common to multiple scripts. There are security
1295 implications if the pathname is not fully specified.
1297 ( ... ) Command grouping
1298 Commands grouped in "( )" are executed in a subshell, with a separate
1299 environment (can not affect the variables in the rest of the script).
1303 Conditional Test Examples
1305 As with most aspects of shell scripting, there are usually several
1306 possible ways to accomplish a task. Certain idioms show up commonly.
1307 These are five ways to examine and branch on the initial character of
1310 Use case with a pattern:
1312 /*) echo "starts with /" ;;
1313 Works in all shells, and uses no extra processes
1316 if [ "`echo $var | cut -c1`" = "/" ] ; then .
1317 Works in all shells, but inefficiently uses a pipe and
1318 external process for a trivial task.
1320 Use POSIX variable truncation:
1321 if [ "${var%${var#?}}" = "/" ]; then
1322 Works with ksh, bash and other POSIX-compliant shells. Not
1323 obvious if you have not seen this one before. Fails on old
1324 Bourne shells. Dave Taylor in "Wicked Cool Shell Scripts"
1327 Use POSIX pattern match inside of [[...]]:
1328 if [[ $var = /* ]]; then
1329 Works with ksh, bash and other POSIX-compliant shells. Note
1330 that you must use [[...]] and no quotes around the pattern.
1332 The [[...]] syntax is handled internally by the shell and
1333 can therefore interpret "wildcard" patterns differently
1334 than an external command. An unquoted wildcard is
1335 interpreted as a pattern to be matched, while a quoted
1336 wildcard is taken literally. The [...] syntax, even if
1337 handled internally, is treated as though it were external
1338 for backward compatability. This requires that wildcard
1339 patterns be expanded to matching filenames.
1341 Use ksh (93 and later) and bash variable substrings:
1342 if [ "${var:0:1}" = "/" ]; then
1343 ksh93 and later versions, and bash, have a syntax for
1344 directly extracting substrings by character position.
1345 ${varname:start:length}
1347 Example: ex17 display, text
1351 Miscellaneous internal commands
1353 The shells (ksh in particular) have many more internal commands. Some
1354 are used more in interactive shells. The commands listed here are
1355 used in scripts, but don't conveniently fit elsewhere in the class.
1358 The args are read as input to the shell and the resulting
1359 command executed. Allows "double" expansion of some
1360 constructs. For example, constructing a variable name out of
1361 pieces, and then obtaining the value of that variable.
1364 NETDEV_1=hme0 # As part of an initialization step defining multiple devices
1366 devnum=1 # As part of a loop over those devices
1367 ifname=$netdev$devnum # construct a variable name NETDEV_1
1368 eval device=\$$ifname # evaluate it - device is set to hme0
1371 The command is executed in place of the current shell. There
1372 is no return from an exec. I/O redirection may be used. This
1373 is also used to change the I/O for the current shell.
1376 The line is variable-expanded, but otherwise treated as a
1377 comment. Sometimes used as a synonym for "true" in a loop.
1380 # this loop will go forever until broken by
1381 # a conditional test inside, or a signal
1385 Remove the named variables. This is not the same as setting
1386 their values to null.
1388 typeset [+/- options] [ name[=value] ] ... (ksh only, bash uses
1389 declare for similar functions)
1390 Set attributes and values for shell variables and functions.
1391 When used inside a function, a local variable is created.
1392 Some of the options are:
1395 Left justify and remove leading blanks. The
1396 variable always has length n if specified.
1399 Right justify and fill with leading blanks. The
1400 variable always has length n if specified.
1403 The named variable is always treated as an
1404 integer. This makes arithmetic faster. The
1405 reserved word integer is an alias for typeset
1409 As for -R, but fill with zeroes if the value
1413 Lower-case convert the named variables
1416 Upper-case convert the named variables
1419 Mark the variables as readonly
1422 Export the named variables to the enviroment
1425 The variables are taken as function names.
1426 Turn on execution tracing.
1430 Manipulating Variables (ksh/bash only)
1434 The pattern in the following uses the same wildcards as for filename
1438 returns the length of $var in characters
1441 removes the shortest suffix of $var patching pattern
1444 removes the longest suffix of $var patching pattern
1447 removes the shortest prefix of $var patching pattern
1450 removes the longest prefix of $var patching pattern
1454 $(( integer expression ))
1455 The $(( ... )) construction interprets the contents as an
1456 arithmetic expression (integer only). Variables are
1457 referenced by name without the "$". Most of the arithmetic
1458 syntax of the 'C' language is supported, including bit
1459 manipulations (*,/,+,-,|,&,<<,>>. Use parentheses for
1460 changing precedence).
1463 datapath=/data/public/project/trials/set1/datafile.dat
1465 filename=${datapath##*/}
1466 filename is set to "datafile.dat" since the longest prefix
1467 pattern matching "*/" is the leading directory path (compare
1471 path is set to "/data/public/project/trials/set1" since the
1472 shortest suffix pattern matching "/*" is the filename in the
1473 last directory (compare dirname)
1476 often used in while loops
1482 All but the earliest versions of sh allow you define shell functions,
1483 which are visible only to the shell script and can be used like any
1484 other command. Shell functions take precedence over external commands
1485 if the same name is used. Functions execute in the same process as
1486 the caller, and must be defined before use (appear earlier in the
1487 file). They allow a script to be broken into maintainable chunks, and
1488 encourage code reuse between scripts.
1492 identifier() { list; }
1493 POSIX syntax for shell functions. Such functions do not
1494 restrict scope of variables or signal traps. The identifier
1495 follows the rules for variable names, but uses a separate
1498 function identifier { list; }
1499 Ksh and bash optional syntax for defining a function. These
1500 functions may define local variables and local signal traps
1501 and so can more easily avoid side effects and be reused by
1504 A function may read or modify any shell variable that exists in the
1505 calling script. Such variables are global.
1507 (ksh and bash only) Functions may also declare local variables in the
1508 function using typeset or declare. Local variables are visible to the
1509 current function and any functions called by it.
1511 return [n], exit [n]
1512 Return from a function with the given value, or exit the
1513 whole script with the given value.
1515 Without a return, the function returns when it reaches the end, and
1516 the value is the exit status of the last command it ran.
1522 # Print an error message and exit with given status
1523 # call as: die status "message" ["message" ...]
1533 Functions are called like any other command. The output may be
1534 redirected independantly of the script, and arguments passed to the
1535 function. Shell option flags like -x are unset in a function - you
1536 must explicitly set them in each function to trace the execution.
1537 Shell functions may even be backgrounded and run asynchronously, or
1538 run as coprocesses (ksh).
1542 [ -w $filename ] || \
1543 die 1 "$file not writeable" "check permissions"
1545 Example: Backgrounded function call. ex12 display, text
1552 6: echo "Background"
1554 8: # Function will return here - if backgrounded, the subprocess will exit.
1557 11: echo "ps before background function"
1560 14: echo "My PID=$$"
1561 15: echo "Background function PID=$!"
1562 16: echo "ps after background function"
1570 # Print or not depending on global "$verbosity"
1571 # Change the verbosity with a single variable.
1572 # Arg. 1 is the level for this message.
1574 if [[ $level -le $verbosity ]]; then
1580 vprint 1 This message will appear
1581 vprint 3 This only appears if verbosity is 3 or higher
1585 By using only command line arguments, not global variables, and
1586 taking care to minimise the side effects of functions, they can be
1587 made reusable by multiple scripts. Typically they would be placed in
1588 a separate file and read with the "." operator.
1590 Functions may generate output to stdout, stderr, or any other file or
1591 filehandle. Messages to stdout may be captured by command
1592 substitution (`myfunction`, which provides another way for a function
1593 to return information to the calling script. Beware of side-effects
1594 (and reducing reusability) in functions which perform I/O.
1600 Unix I/O is performed by assigning file descriptors to files or
1601 devices, and then using those descriptors for reading and writing.
1602 Descriptors 0, 1, and 2 are always used for stdin, stdout and stderr
1603 respectively. Stdin defaults to the keyboard, while stdout and stderr
1604 both default to the current terminal window.
1606 Redirecting for the whole script
1608 Redirecting stdout, stderr and other file descriptors for the whole
1609 script can be done with the exec command.
1611 exec > outfile < infile
1612 with no command, the exec just reassigns the I/O of the
1616 The form n<, n> opens file descriptor n instead of the
1617 default stdin/stdout. This can then be used with read -u or
1620 Explicitly opening or duplicating file descriptors
1622 One reason to do this is to save the current state of stdin/stdout,
1623 temporarily reassign them, then restore them.
1626 standard output is moved to whatever file descriptor n is
1627 currently pointing to
1630 standard input is moved to whatever file descriptor n is
1631 currently pointing to
1634 file descriptor n is opened for writing on the named file.
1637 file descriptor n is set to whatever file descriptor 1 is
1638 currently pointing to.
1640 Example Sending messages to stderr (2) instead of stdout (1)
1642 echo "Error: program failed" >&2
1644 Echo always writes to stdout, but stdout can be temporarily
1645 reassigned to duplicate stderr (or other file descriptors).
1646 Conventionally Unix programs send error messages to stderr to keep
1647 them separated from stdout.
1649 Input and output to open file descriptors (ksh)
1651 Printing to file descriptors (usually more efficient than
1655 print to file descriptor n.
1658 write to the pipe to a coprocess (opened by |&)
1660 Reading from file descriptors other than stdin:
1662 read -u n var1 var2 rest
1663 read a line from file descriptor n, parsing by $IFS, and
1664 placing the words into the named variables. Any left over
1665 words all go into the last variable.
1668 read from the pipe to a coprocess (opened by |&)
1670 Closing file handles
1673 standard input is explicitly closed
1676 standard output is explicitly closed
1678 For example, to indicate to another program downstream in a pipeline
1679 that no more data will be coming. All file descriptors are closed
1680 when a script exits.
1682 I/O redirection operators are evaluated left-to-right. This makes a
1683 difference in a statement like: ">filename 2>&1". (Many books with
1684 example scripts get this wrong)
1689 redirect input to the temporary file formed by everything up
1690 the matching string at the start of a line. Allows for
1691 placing file content inline in a script.
1693 Example: ex5 display, text
1696 2: echo "Example of unquoted here document, with variable and command substitution"
1699 5: This text will be fed to the "cat" program as
1700 6: standard input. It will also have variable
1701 7: and command substitutions performed.
1702 8: I am logged in as $USER and today is `date`
1705 11: echo "Example of quoted here document, with no variable or command substitution"
1706 12: # The terminating string must be at the start of a line.
1707 13: cat <<"EndOfInput"
1708 14: This text will be fed to the "cat" program as standard
1709 15: input. Since the text string marking the end was quoted, it does not get
1710 16: variable and command subsitutions.
1711 17: I am logged in as $USER and today is `date`
1714 Example: duplex display, text
1717 2: # Add in the magic postscript preface to perform
1718 3: # duplex printer control for Xerox docuprint.
1720 5: # To have this script send the files directly to the printer, use
1721 6: # a subshell to collect the output of the two 'cat' commands.
1726 11: %%BeginFeature: *Duplex DuplexTumble
1727 12: <</Duplex true /Tumble false>> setpagedevice
1737 More complicated manipulations of file descriptors can be arranged.
1738 Two such examples are shown here:
1740 This short test script can be used to generate suitable output.
1743 echo "This goes to stdout"
1744 echo "This goes to stdout and has foo in the line"
1745 echo "This goes to stderr" >&2
1748 Pass stderr of a command into a pipeline for further processing
1750 Example: ex14 display, text
1753 ./ex13.sh 2>&1 1>&3 3>&- | sed 's/stderr/STDERR/' 1>&2
1755 We duplicate stdout to another file descriptor (3), then run the
1756 first command with stderr redirected to stdout and stdout redirected
1757 to the saved descriptor (3). The result is piped into other commands
1758 as needed. The output of the pipeline is redirected back to stderr,
1759 so that stdout and stderr of the script as a whole are what we
1764 3: # Take stderr from a command and pass it into a pipe
1765 4: # for further processing.
1767 6: # Uses ex13.sh to generate some output to stderr
1768 7: # stdout of ex13 is processed normally
1770 9: # Save a copy of original stdout
1773 12: # stdout from ex13.sh is directed to the original stdout (3)
1774 13: # stderr is passed into the pipe for further processing.
1775 14: # stdout from the pipe is redirected back to stderr
1776 15: ./ex13.sh 2>&1 1>&3 3>&- | sed 's/stderr/STDERR/' 1>&2
1778 17: # 3 is closed before running the command, just in case it cares
1779 18: # about inheriting open file descriptors.
1781 Capture the exit status of a command in the middle of a pipeline
1783 Example: ex15 display, text
1786 ex13stat=`((./ex13.sh; echo $? >&4) | grep 'foo' 1>&3) 4>&1`
1788 This script uses nested subshells captured in backtics. Again we
1789 first duplicate stdout to another file descriptor (3). The inner
1790 subshell runs the first command, then writes the exit status to fd 4.
1791 The outer subshell redirects 4 to stdout so that it is captured by
1792 the backtics. Standard output from the first command (inner subshell)
1793 is passed into the pipeline as normal, but the final output of the
1794 pipeline is redirected to 3 so that it appears on the original stdout
1795 and is not captured by the backtics.
1797 If any of the commands really care about inheriting open file
1798 descriptors that they don't need then a more correct command line
1799 closes the descriptors before running the commands.
1804 4: # Uses ex13.sh to generate some output and give us an
1805 5: # exit status to capture.
1807 7: # Get the exit status of ex13 into $ex13stat.
1808 8: # stdout of ex13 is processed normally
1810 10: # Save a copy of stdout
1812 12: # Run a subshell, with 4 duplicated to 1 so we get it in stdout.
1813 13: # Capture the output in ``
1814 14: # ex13stat=`( ... ) 4>&1`
1815 15: # Inside the subshell, run another subshell to execute ex13,
1816 16: # and echo the status code to 4
1817 17: # (./ex13.sh; echo $? >&4)
1818 18: # stdout from the inner subshell is processed normally, but the
1819 19: # subsequent output must be directed to 3 so it goes to the
1820 20: # original stdout and not be captured by the ``
1821 21: ex13stat=`((./ex13.sh; echo $? >&4) | grep 'foo' 1>&3) 4>&1`
1823 23: echo Last command status=$?
1824 24: echo ex13stat=$ex13stat
1826 26: # If any of the commands really care about inheriting open file
1827 27: # descriptors that they don't need then a more correct command line
1828 28: # closes the descriptors before running the commands
1830 30: ex13stat=`((./ex13.sh 3>&- 4>&- ; echo $? >&4) | \
1831 31: grep 'foo' 1>&3 3>&- 4>&- ) 4>&1`
1832 32: echo Last command status=$?
1833 33: echo ex13stat=$ex13stat
1835 Combine the above two techniques:
1837 Example: ex16 display, text
1840 ex13stat=`((./ex13.sh 2>&1 1>&3 3>&- 4>&- ; echo $? >&4) | \
1841 sed s/err/ERR/ 1>&2 3>&- 4>&- ) 4>&1`
1846 4: # Uses ex13.sh to generate some output and give us an
1847 5: # exit status to capture.
1849 7: # Get the exit status of ex13 into ex13stat.
1850 8: # stderr of ex13 is processed by the pipe, stdout
1853 11: # Save a copy of stdout
1856 14: # Run a subshell, with 4 copied to 1 so we get it in stdout.
1857 15: # Capture the output in backtics`
1858 16: # ex13stat=`( ) 4>&1`
1860 18: # In the subshell, run another subshell to execute ex13, and
1861 19: # echo the status code to 4
1862 20: # (./ex13.sh; echo $? >&4)
1864 22: # stdout from the inner subshell is directed to the original stdout (3)
1865 23: # stderr is passed into the pipe for further processing.
1866 24: # stdout from the pipe is redirected back to stderr
1868 26: # Close the extra descriptors before running the commands
1870 28: ex13stat=`((./ex13.sh 2>&1 1>&3 3>&- 4>&- ; echo $? >&4) | \
1871 29: sed s/err/ERR/ 1>&2 3>&- 4>&- ) 4>&1`
1873 31: echo Last command status=$?
1874 32: echo ex13stat=$ex13stat
1877 A practical application of this would be running a utility such as dd
1878 where the exit status is important to capture, but the error output
1879 is overly chatty and may need to be filtered before delivering to
1880 other parts of a script.
1884 Coprocesses and Background jobs
1886 Scripts can start any number of background jobs (any external
1887 command), which run in parallel with the parent script, and
1888 asynchronously. Processes which require no further interaction or
1889 synchronization (fire and forget) are easy. Interaction with
1890 background jobs is tricky. You can use signals, pipes, named pipes,
1891 or disk files for communication.
1894 Start command as a background process. Control returns
1895 immediately to the shell.
1898 The special variable $! contains the process ID of the last
1899 background job that was started. You can save that and
1900 examine the process later (ps -p $bgpid) or send it a signal
1905 Coprocesses are a way of starting a separate process which runs
1906 asychronously, but has stdin/stdout connected to the parent script
1910 Start a coprocess with a 2-way pipe to it
1913 Read from the pipe to the coprocess, instead of standard
1917 Write to the pipe connected to the coprocess, instead of
1920 Multiple coprocesses can be handled by moving the special file
1921 descriptors connected to the pipes onto standard input and output,
1922 and or to explicitly specified file descriptors.
1925 The input from the coprocess is moved to standard input
1928 The output from the coprocess is moved to standard output
1930 Example: ex9 display, text
1931 A script wants to save a copy of all output in a file, but also wants
1932 a copy to the screen. This is equivalent to always running the script
1934 script | tee outfile
1938 3: # If we have not redirected standard output, save a copy of
1939 4: # the output of this script into a file, but still send a
1940 5: # copy to the screen.
1942 7: if [[ -t 1 ]] ; then
1943 8: # Only do this if fd 1 (stdout) is still connected
1946 11: # We want the standard output of the "tee" process
1947 12: # to go explicitly to the screen (/dev/tty)
1948 13: # and the second copy goes into a logfile named $0.out
1950 15: tee $0.out >/dev/tty |&
1952 17: # Our stdout all goes into this coprocess
1956 21: # Now generate some output
1957 22: print "User activity snapshot on $(hostname) at $(date)"
1961 Example: ex10 display, text
1962 Start a coprocess to look up usernames in some database. It is faster
1963 to run a single process than to run a separate lookup for each user.
1966 2: # This example uses a locally written tool for Dartmouth Name Directory lookups
1968 4: # Start the dndlookup program as a coprocess
1969 5: # Tell it to output only the canonical full name, and to not print multiple matches
1970 6: dndlookup -fname -u |&
1972 8: # move the input/output streams so we
1973 9: # can use other coprocesses too
1977 13: echo "Name file contents:"
1981 17: # read the names from a file "namefile"
1982 18: while read uname; do
1983 19: print -u4 $uname
1984 20: read -u5 dndname
1985 21: case $dndname in
1986 22: *many\ matches*)
1987 23: # handle case where the name wasn't unique
1988 24: print "Multiple matches to \"$uname\" in DND"
1991 27: # handle case where the name wasn't found
1992 28: print "No matches to \"$uname\" in DND"
1995 31: # we seem to have a hit - process the
1996 32: # canonical named retrieved from dndlookup
1997 33: print "Unique DND match: full name for \"$uname\" is \"$dndname\""
2003 39: # We've read all the names, but the coprocess
2004 40: # is still running. Close the pipe to tell it
2005 41: # we have finished.
2012 Both ksh and bash implement arrays of variables, but in somewhat
2015 ksh distinguishes between numerically indexed (small) arrays, and
2016 string indexed (associative) arrays. bash uses integers for all array
2017 indexing, but the integers need not be consecutive and unassigned
2018 array elements do not exist. Arrays must be declared before use, e,g.
2019 typeset -A myarray (ksh associative array), or typeset -a myarray
2022 Array elements are set with the syntax: myarray[index]=value and
2023 referenced with the syntax ${myarray[index]}
2025 This example shows use of an array indexed by IP addresses, as
2026 strings in ksh or as non-consecutive numbers in bash. It also
2027 demonstrates use of getopt for options processing
2029 Example: getauthlogs display, text
2033 3: # First attempt at a consolidated auth log collection from kaserver
2034 4: # Timestamps in the raw files are NOT designed for easy sorting.
2037 7: # -i -- translate hex IP addresses to dotted-decimal (relatively quick)
2038 8: # -h -- translate hex IP addresses to DNS names (somewhat slower - DNS lookups)
2039 9: # -u user -- filter for the named user before translating addresses
2043 13: # convert the IP address in reverse-hex to dotted-decimal
2044 14: echo $((0x${1:6:2})).$((0x${1:4:2})).$((0x${1:2:2})).$((0x${1:0:2}))
2049 19: # Convert a decimal IP to hostname - calls 'host' each time
2050 20: hostname=$(host $1)
2051 21: case $hostname in
2053 23: # Just echo the address we tried to look up
2057 27: # The result is word 5. Lower-case it for consistency
2059 29: echo "$5" | tr 'A-Z' 'a-z'
2068 38: while getopts ihu: o ; do
2070 40: i) iptranslate=1 ;;
2071 41: h) gethostnames=1; iptranslate=1 ;;
2072 42: u) filter="grep $OPTARG" ;;
2075 45: shift $(($OPTIND-1))
2077 47: # We could get the DB server names from 'fs checkservers', but it isn't obvious what is from our cell. We
2078 48: # could also grep CellServDB. I cop out and hard code one known DB server and get the others from it.
2079 49: masterserver=halley.dartmouth.edu
2080 50: serverlist=$(bos listhosts -server $masterserver| grep 'Host .* is ' | awk '{print $4}')
2082 52: # If we want to filter usernames, it is more efficient to do it inline, before sorting, translation and hostname lookups
2084 54: # Array to hold IP address/name conversions (associative array, ksh only)
2085 55: # ksh - use -A for associative array. bash - use -a and numeric array
2086 56: typeset -a hostnames
2089 59: for dbserver in $serverlist; do
2090 60: bos getlog -server $dbserver -file /usr/afs/logs/AuthLog
2092 62: ) | grep -v 'Fetching log file' | $filter | sed -e 's/^... //' -e 's/ \([1-9]\) / 0\1 /' | sort --month-sort | \
2093 63: sed '-e s/ \([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)$/ 0\1/' |
2094 64: while read line; do
2095 65: if [[ $iptranslate == 1 ]] ; then
2097 67: # Sometimes we get a 7-digit hex code in the log - the kaserver apparently drops leading zeros.
2098 68: # The second 'sed' in the pipe catches these are fixes them.
2100 70: *\ from\ [0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])
2101 71: # translate the reverse-hex address
2102 72: iphex=${line##* from }
2103 73: # bash version - index by numeric value only, but can be sparse array -- use the raw IP
2104 74: ipdec=$((0x$iphex))
2105 75: frontpart=${line% from *}
2106 76: if [[ $gethostnames == 1 ]]; then
2107 77: # ksh - index on hex value as a string (iphex)
2108 78: # bash - index on numeric value (ipdec)
2110 80: if [[ -z "${hostnames[$index]}" ]]; then
2111 81: hostnames[$index]="$(hostlookup $(hextodec $iphex))"
2113 83: echo "$frontpart from ${hostnames[$index]}"
2115 85: echo "$frontpart from $(hextodec $iphex)"
2123 93: # No ip translation, just echo the whole line
2131 Delivering and Trapping Signals
2133 Unix signals (software interrupts) can be sent as asynchronous events
2134 to shell scripts, just as they can to any other program. The default
2135 behaviour is to ignore some signals and immediately exit on others.
2136 Scripts may detect signals and divert control to a handler function
2137 or external program. This is often used to perform clean-up actions
2138 before exiting, or restart certain procedures. Execution resumes
2139 where it left off, if the signal handler returns. Signal traps must
2140 be set separately inside of shell functions. Signals can be sent to a
2143 trap handler sig ...
2144 handler is a command to be read (evaluated first) and
2145 executed on receipt of the specified sigs. Signals can be
2146 specified by name or number (see kill(1)) e.g. HUP, INT,
2147 QUIT, TERM. A Ctrl-C at the terminal generates a INT.
2149 * A handler of - resets the signals to their default values
2150 * A handler of '' (null) ignores the signals
2151 * Special signal values are as follows:
2154 the handler is called when the function exits, or
2155 when the whole script exits. The exit signal has
2159 the handler is called when any command has a
2160 non-zero exit status
2163 the handler is called after each command.
2165 Example: ex8 display, text
2168 2: # Try this under bash, ksh and sh
2170 4: trap huphandler HUP
2172 6: trap exithandler TERM INT
2176 10: echo 'Received SIGHUP'
2177 11: echo "continuing"
2182 16: echo 'Received SIGTERM or SIGINT'
2185 19: ## Execution starts here - infinite loop until interrupted
2186 20: # Use ":" or "true" for infinite loop
2187 21: # SECONDS is built-in to bash and ksh. It is number of seconds since script started
2188 22: : is like a comment, but it is evaluated for side effects and evaluates to true
2191 25: # while true; do
2193 27: seconds=$((seconds + 5))
2194 28: echo -n "$SECONDS $seconds - "
2197 Exit handlers can be defined to clean up temporary files or reset the
2198 state of devices. This can be useful if the script has multiple
2199 possible exit points.
2203 Security issues in shell scripts
2205 Shell scripts are often used by system administrators and are run as
2208 * Don't use set-UID scripts.
2210 Most systems don't even allow a script to be made set-UID. It
2211 is impossible (due to inherent race conditions) to ensure that
2212 a set-uid script cannot be compromised. Use wrapper programs
2215 * Always explicitly set $PATH at the start of a script, so that you
2216 know exactly which external programs will be used.
2218 * If possible, don't use temporary files. If they cannot be
2219 avoided, use $TMPDIR, and create files safely (e.g. mktemp).
2221 Often scripts will write to a fixed, or trivially generated
2222 temporary filename in /tmp. If the file already exists and you
2223 don't have permission to overwrite it, the script will fail. If
2224 you do have permission to overwrite it, you will delete the
2225 previous contents. Since /tmp is public write, another user may
2226 create files in it, or possibly fill it completely.
2228 1. A link is created by an unprivileged user in /tmp:
2229 /tmp/scratch -> /vmunix
2230 2. A root user runs a script that blindly writes a scratch
2231 file to /tmp/scratch, and overwrites the operating system.
2232 Environment variable $TMPDIR is often used to indicate a
2233 preferred location for temporary files (e.g., a per-user
2234 directory). Some systems may use $TMP or $TEMP. Safe scratch
2235 files can be made by creating a new directory, owned and
2236 writeable only by you, then creating files in there.
2239 (umask 077 && mkdir /tmp/tempdir.$$) || exit 1
2244 tmp=$tmp/tempdir.$RANDOM.$RANDOM.$RANDOM.$$
2245 (umask 077 && mkdir $tmp) || {
2246 echo "Could not create temporary directory" 1>&2
2250 Alternatively, many systems have mktemp to safely create a
2251 temporary file and return the filename, which can be used by
2252 the script and then deleted.
2254 * Check exit status of everything you do.
2256 * Don't trust user input
2258 * data piped from other programs
2259 * file names. Output of filename generation with wildcards, or
2260 directly from ls or find
2263 Consider the effects of a file named "myfile;cd /;rm *" if processed,
2264 unquoted, by your script.
2266 One possible way to protect against weirdo characters in file
2269 # A function to massage a list of filenames
2270 # to protect weirdo characters
2271 # e.g. find ... | protect_filenames | xargs command
2273 # We are backslash-protecting the characters \'" ?*;
2276 sed -es/\\\\/\\\\\\\\/g \
2285 If using GNU find and xargs, there is a much cleaner option to
2286 null-terminate generated pathnames.
2292 Shell scripts are very frequently written quickly for a single
2293 purpose, used once and discarded. They are also as frequently kept
2294 and used many times, and migrate into other uses, but often do not
2295 receive the same level of testing and debugging that other software
2296 would be given in the same situation. It is possible to apply general
2297 principles of good software engineering to shell scripts.
2298 * Preface scripts with a statement of purpose, author, date and
2300 * Use a revision control system for complex scripts with a long
2302 * Assume your script will have a long lifetime unless you are
2304 * Document any non-standard external utilities which your script
2306 * Document your scripts with inline comments - you'll need them in
2307 a few months when you edit it.
2308 * Treat standard input and output in the normal way, so that your
2309 script can be used in combination with other programs (the Unix
2311 * Be consistent in the format of your output, so that other
2312 programs can rely on it
2313 * Use options to control behaviour such as verbosity of output.
2314 Overly chatty programs are very hard to combine with other
2316 * Use interactive features (prompting the user for information)
2317 very sparingly. Doing so renders the script unuseable in pipeline
2318 combinations with other programs, or in unattended operations.
2321 When not to use shell scripts
2323 * If an existing tool already does what you need - use it.
2324 * If the script is more than a few hundred lines, you are probably
2325 using the wrong tool.
2326 * If performance is horrible, and the script is used a lot, you
2327 might want to consider another language.
2331 Some longer examples
2333 The class accounts have directories with all of the examples from the
2334 books by Blinn, Michael, Rosenblatt, and Taylor. These can also be
2335 downloaded (see the References page). Some of these are linked below
2336 (but not included in the printed notes), with additional comments.
2338 Download a compressed tar file of all example scripts used in these
2341 * postprint display, text
2342 A wrapper script for printing a mix of text and postscript files
2344 * checkpath display, text
2345 Check all the directories in the $PATH for possibly conflicting
2348 * run-with-timeout display, text
2349 Run a command with a timeout. Kill the command if it hasn't
2350 finished when the timeout expires.
2352 * MailPkg display, text
2353 Tar, compress, split and uuendcode a set of files for mailing.
2356 * Ptree (original) display, text
2357 * Ptree (ksh version) display, text
2358 Runs "ps" to get a process listing and then reformats to show the
2359 process family hierarchies. The original example is pure Bourne
2360 shell and inefficient. The ksh version is a fairly simple
2361 translation to use ksh internal commands where possible, and
2362 avoid writing scratch files, and runs very much faster. (Blinn).
2364 This entire tutorial was created from individual HTML pages using a
2365 content management system written as ksh scripts (heavily using sed
2366 to edit the pages), coordinated by make.
2368 You can even write an entire web server as a shell script. This one
2369 is part of the LEAF (Linux Embedded Appliance Firewall) project. This
2370 wouldn't be suitable for much load, but handles occasional queries on
2371 static HTML and CGI scripts. (www.nisi.ab.ca/lrp/Packages/weblet.htm)
2372 * sh-httpd display, text
2376 A Toolkit of commonly used external commands
2378 The following commands are very frequently used in shell scripts.
2379 Many of them are used in the examples in these notes. This is just a
2380 brief recap -- see the man pages for details on usage. The most
2381 useful are flagged with *.
2383 Most of these commands will operate on a one or more named files, or
2384 will operate on a stream of data from standard input if no files are
2387 Listing, copying and moving files and directories
2390 list contents of a directory, or list details of files and
2394 Make and Remove directories.
2397 Remove (delete), Copy and Move (rename) files and directories
2400 Update the last modifed timestamp on a file, to make it
2401 appear to have just been written.
2403 If the file does not exist, a new zero-byte file is
2404 created, which is often useful to signify that an event has
2408 Make a duplicate copy of a data stream - used in pipelines to
2409 send one copy to a log file and a second copy on to another
2410 program. (Think plumbing).
2412 Displaying text, files or parts of files
2415 Echo the arguments to standard output -- used for messages
2416 from scripts. Some versions of "sh", and all csh/ksh/bash
2417 shells internalized "echo".
2419 Conflicts sometimes arise over the syntax for echoing a
2420 line with no trailing CR/LF. Some use "\c" and some use
2421 option "-n". To avoid these problems, ksh also provides the
2422 "print" command for output.
2425 Copy and concatenate files; display contents of a file
2428 Display the beginning of a file, or the end of it.
2431 Extract selected fields from each line of a file. Often awk
2432 is easier to use, even though it is a more complex program.
2435 Count lines, words and characters in the input.
2437 Compression and archiving
2439 compress; gzip, zip; tar *
2440 Various utilities to compress/uncompress individual files,
2441 combine multiple files into a single archive, or do both.
2443 Sorting and searching for patterns
2446 Sort data alphabetically or numerically.
2449 Search a file for lines containing character patterns. The
2450 patterns can be simple fixed text, or very complex regular
2453 The name comes from "Global Regular Expression and Print"
2454 -- a function from the Unix editors which was used
2455 frequently enough to warrant getting its own program.
2458 Remove duplicate lines, and generate a count of repeated
2462 Count lines, words and characters in a file.
2464 System information (users, processes, time)
2467 Display the current date and time (flexible format). Useful
2468 for conditional execution based on time, and for timestamping
2472 List the to a running processes.
2475 Send a signal (interrupt) to a running process.
2478 Print the user name and UID and group of the current user
2479 (e.g. to distinguish priviledged users before attempting to
2480 run programs which may fail with permission errors)
2483 Display who is logged on the system, and from where they
2487 Display information about the system, OS version, hardware
2491 Send mail, from a file or standard input, to named
2492 recipients. Since scripts are often used to automate
2493 long-running background jobs, sending notification of
2494 completion by mail is a common trick.
2497 Place a message in the central system logging facility.
2498 Scripts can submit messages with all the facilities available
2499 to compiled programs.
2502 Display the hostname of the current host - usful to keep
2503 track of where your programs are running
2508 The conditional test, used extensively in scripts, is also an
2509 external program which evaluates the expression given as an
2510 argument and returns true (0) or false (1) exit status. The
2511 name "[" is a link to the "test" program, so a line like:
2513 actually runs a program "[", with arguments "-w logfile ]",
2514 and returns a true/false value to the "if" command.
2516 In ksh and most newer versions of sh, "[" is replaced with
2517 a compatible internal command, but the argument parsing is
2518 performed as if it were an external command. Ksh also
2519 provides the internal "[[" operator, with simplified
2525 A pattern matching and data manipulation utility, which has
2526 its own scripting language. It also duplicates much
2527 functionality from 'sed','grep','cut','wc', etc.
2529 Complex scripts can be written entirely using awk, but it
2530 is frequently used just to extract fields from lines of a
2531 file (similar to 'cut').
2534 Stream Editor. A flexible editor which operates by applying
2535 editing rules to every line in a data stream in turn.
2537 Since it makes a single pass through the file, keeping only
2538 a few lines in memory at once, it can be used with
2539 infinitely large data sets. It is mostly used for global
2540 search and replace operations. It is a superset of 'tr',
2541 'grep', and 'cut', but is more complicated to use.
2544 Transliterate - perform very simple single-character edits on
2547 Finding and comparing files
2550 Search the filesystem and find files matching certain
2551 criteria (name pattern, age, owner, size, last modified etc.)
2554 Apply multiple filename arguments to a named command and run
2557 Xargs is often used in combination with "find" to apply
2558 some command to all the files matching certain criteria.
2559 Since "find" may result in a very large list of pathnames,
2560 using the results directly may overflow command line
2561 buffers. Xargs avoids this problem, and is much more
2562 efficient than running a command on every pathname
2566 Compare two files and list the differences between them.
2569 Returns the base filename portion of the named pathname,
2570 stripping off all the directories
2573 Returns the directory portion of the named pathname,
2574 stripping off the filename
2576 Arithmetic and String Manipulation
2579 The "expr" command takes an numeric or text pattern
2580 expression as an argument, evaluates it, and returns a result
2581 to stdout. The original Bourne shell had no built-in
2582 arithmetic operators. E.g.
2584 expr 2 '*' '(' 21 + 3 ')'
2585 Used with text strings, "expr" can match regular expressions
2586 and extract sub expressions. Similar functionality can be
2587 achived with sed. e.g.
2588 expr SP99302L.Z00 : '[A-Z0-9]\{4\}\([0-9]\{3\}\)L\.*'
2591 Desk Calculator - an RPN calculator, using arbitrary
2592 precision arithmetic and user-specified bases. Useful for
2593 more complex arithmetic expressions than can be performed
2594 internally or using expr
2597 A preprocessor for dc which provides infix notation and a
2598 C-like syntax for expressions and functions.
2603 Merge lines from multiple files into tab-delimited columns.
2606 Perform a join (in the relational database sense) of lines in
2607 two sorted input files.
2611 References, Resources, Man pages etc.
2613 The standard man pages for sh and ksh are quite complete, but not
2614 easy to learn from. The following is a sampling of the many available
2615 books on the subject. The Bolsky and Korn book might be viewed as the
2616 standard "reference". The Blinn book is Bourne shell, but everything
2617 in it should work for either shell.
2618 The links are to publisher's web sites, or Amazon.com. Some links are
2619 also given to the example scripts provided with the books.
2623 * The New KornShell Command And Programming Language, by Morris I.
2624 Bolsky, David G. Korn (Contributor). More info
2626 * Learning the Korn Shell, 2nd Edn. by Bill Rosenblatt and Arnold
2629 * Korn Shell Programming by Example, by Dennis O'Brien, David Pitts
2630 (Contributor). More info
2632 * The Korn Shell Linux and Unix Programming Manual (2nd Edn) by
2633 Anatole Olczak. More info
2635 * Portable Shell Programming: An Extensive Collection of Bourne
2636 Shell Examples by Bruce Blinn. More info
2637 Examples from this book can be downloaded for study.
2639 * Linux Shell Scripting with Bash by Ken O. Burtch. More info
2641 * Unix Shell Programming by Stephen Kochan and Patrick Wood (third
2644 * Teach yourself Shell Programming in 24 Hours, by S.
2645 Veeraraghavan. SAMS 2nd Edn. (2002) More info
2647 * Mastering Unix Shell Scripting by Randal K. Michael, Wiley (2003)
2648 More info Light on basics, but develops scripting through
2649 examples. Ksh only. Examples can be downloaded from the Wiley
2650 site (www.wiley.com/legacy/compbooks/michael/).
2652 * Wicked Cool Shell Scripts by Dave Taylor, No Starch Press (2004)
2653 More info Develops scripting entirely through examples, drawn
2654 from Linux and OSX in addition to traditional Unix. Recommended,
2655 but not for beginners. Examples can be downloaded from the
2657 (www.intuitive.com/wicked/wicked-cool-shell-script-library.shtml).
2659 * Unix Power Tools, by S. Powers, J. Peek, T. O'Reilly, M. Loudikes
2664 * Shelldorado (http://www.shelldorado.com)
2665 Lots of links to scripting resources
2667 * Kornshell (http://www.kornshell.com)
2668 The official Korn shell home page, with download links.
2670 * Mac OSX Unix tutorial
2671 (http://www.osxfaq.com/Tutorials/LearningCenter/)
2672 Good resource on advanced use of OSX and Unix shell scripting in
2675 Unix-like shells and utilities for Microsoft Windows
2677 * U/Win (http://www.research.att.com/sw/tools/uwin/)
2678 A free port of ksh and Unix command line utilities, plus Windows
2679 DLL for Unix compatability. Developed by AT&T Research.
2681 * Cygwin (http://www.cygwin.com/)
2682 A free Linux-like environment for Windows. Provides bash, command
2683 line utilities and DLLs. Developed by RedHat. An X server is also
2686 * MKS Toolkit (http://www.mkssoftware.com/)
2687 A commercial ksh clone and command line utilities, plus DLL for
2688 Unix compatability. An X server is also available.
2690 * Microsoft Services for UNIX
2691 (http://www.microsoft.com/windows/sfu/)
2692 A POSIX environment for Windows, with ksh, csh, command line
2693 tools, libraries and software development tools. Developed by
2694 Interix and bought by Microsoft. Free download.
2696 ----------------------------------------------------------------------
2698 Unix shell scripting with ksh/bash: Course Handout
2699 [an error occurred while processing this directive] (last update 22
2700 March 2012) ©Dartmouth College
2701 http://www.dartmouth.edu/~rc/classes/ksh