update repository
[cmdllinux.git] / bash_n_examples / bash / fd / print_pages.html.txt
blob30305d2ac8d4278e4df8f9ff4def3029ff70885f
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
17        scripts.
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
20    hours.
22    Assumptions:
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
32    ].
34    Some descriptions in these notes have more detail available, and are
35    denoted like this:
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
45    redistribute.
47      These notes are updated from time to time. The "development" set of
48      notes are http://northstar-www.dartmouth.edu/~richard/classes/ksh
49      (Dartmouth only)
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      ----------------------------------------------------------------------
59                                Table of Contents
61     1. What is a shell script        
62     2. Why use shell scripts         
63     3. History                       
64     4. Feature comparison            
65     5. Other scripting languages     
66     6. ksh/bash vs sh                
67     7. Basics                        
68     8. Filename Wildcards            
69     9. Variables                     
70    10. Preset Variables              
71    11. Arguments                     
72    12. Shell options                 
73    13. Command substitution          
74    14. I/O redirection and pipelines 
75    15. Input and output              
76    16. Conditional Tests             
77    17. Conditional Tests (contd.)    
78    18. Flow control                  
79    19. Flow control (contd.)         
80    20. Conditional test examples     
81    21. Miscellaneous                 
82    22. Manipulating Variables        
83    23. Functions                     
84    24. Advanced I/O                  
85    25. Wizard I/O                    
86    26. Coprocesses                   
87    27. Arrays                        
88    28. Signals                       
89    29. Security                      
90    30. Style                         
91    31. Examples                      
92    32. Common external commands      
93    33. References                    
95                                                                           (1)
97                              What is a Shell Script
99      * A text file containing commands which could have been typed directly
100        into the shell.
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
110        parts alone.
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:
125        ksh myscript
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).
129        chmod +x myscript
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
132    command.
134    Example: ex0 display, text
136     1: #!/bin/sh
137     2: date
138     3: pwd
139     4: du -k
141                                                                           (2)
143                              Why use Shell Scripts
145      * Combine lengthy and repetitive sequences of commands into a single,
146        simple command.
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)
174 Typical uses
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
197                                                                           (3)
199                                History of Shells
201    sh
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
206            like Unix.
208    csh
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.
214    tcsh
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.
224    ksh
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
251    bash
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
256            compatability.
258    zsh
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
262            MacOSX systems.
264                                                                           (4)
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
280        back.
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
289        interpretation.
290      * Home directory expansion using ~user (except for sh)
292      * # comments
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
306        export
307      * Syntax for redirecting I/O streams other than stdin/stdout
308      * Login startup files (.cshrc and .login, vs .profile) and default
309        options
310      * Reading other shell scripts into the current shell (source filename,
311        vs . filename)
312      * Handling of signals (interrupts)
314                                                                           (5)
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
325        available by default
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:
331      * awk
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.
337      * perl
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
344          command line
346      * python
348          An object-oriented scripting language. Commonly installed by default
349          on modern systems.
351      * tcl/tk
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
362          applications.
364                                                                           (6)
366                                  ksh/bash vs sh
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
382      replaced.
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
397    simpler.
399    The sh and ksh man pages use the term special command for the internal
400    commands - handled by the shell itself.
402                                                                           (7)
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
409    above, apply.
410    In addition:
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
425              character.
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
431            commands.
433    Example: ex1 display, text
435     1: #!/bin/ksh
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
439     5:
440     6: # Line numbers on the left are not part of the script.
441     7: # They are just added to the HTML for reference.
442     8:
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`"
446    12:
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
451    17: ls -C
452    18: # Summarize the disk usage
453    19: print
454    20: print Disk space usage
455    21: du -k
456    22: exit 0
458 Exit status
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.
470                                                                           (8)
472                                Filename Wildcards
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.
483    *
484            Match zero or more characters.
486    ?
487            Match any single character
489    [...]
490            Match any single character from the bracketed set. A range of
491            characters can be specified with [ - ]
493    [!...]
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
502    Example:
503    chapter[1-5].* could match chapter1.tex, chapter4.tex, chapter5.tex.old.
504    It would not match chapter10.tex or chapter1
506                                                                           (9)
508                                 Shell Variables
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
517    variables is safest.
519   Setting and exporting variables
521    srcfile=dataset1
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
527            the "=".
529    set
530            Display all the variables currently set in the shell
532    unset srcfile
533            Remove the variable "srcfile"
535    srcfile=
536            Give the variable a null value, (not the same as removing it).
538    export srcfile
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.
543    export
544            List all the variables currently being exported - this is the
545            environment which will be passed to external programs.
547   Using variables
549    $srcfile
550            Prefacing the variable name with $ causes the value of the
551            variable to be substituted in place of the name.
553    ${srcfile}
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.
559            Example:
561  datafile=census2000
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.
571    ${datafile-default}
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.
577    ${datafile=default}
578            Similar to the above, except if datafile has not been defined, set
579            it to the string "default".
581    ${datafile+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
584            used.
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
606                                                                          (10)
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
614    shell.
615    Try running set or env
616    These are some of the more commonly used ones:
618 Login environment
620    $USER, $LOGNAME
621            Preset to the currently logged-in username.
623    $PATH
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.
629    $TERM
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.
635    $PAGER
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.
643    $EDITOR
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
649            interactive shells.
651 Shell internal settings
653    $PWD
654            Always set the current working directory (readonly)
656    $OLDPWD
657            The previous directory (before the most recent cd command).
658            However, changing directories in a script is often dangerous.
660    $? (readonly)
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.
665    $-
666            Set to the currently set options flags.
668    $IFS
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.
674 Process ID variables
676    $$ (readonly)
677            Set to the process ID of the current shell - useful in making
678            unique temporary files, e.g. /tmp/$0.$$
680    $PPID (readonly)
681            Set to the process ID of the parent process of this shell - useful
682            for discovering how the script was called.
684    $! (readonly)
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
690    $SECONDS (readonly)
691            Integer number of seconds since this shell was started. Can be
692            used for timing commands.
694    $RANDOM
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
697            generator.
699    $LINENO (readonly)
700            Always evaluates to the current line number of the script being
701            executed - useful for debugging.
703                                                                          (11)
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
713      them.
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:
720    $0, $1, $2, ... $9
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.
725    ${10}, ${11}, ...
726            Positional arguments greater than 9 are set by ksh and bash.
727            Remember to use braces to refer to them.
729    shift
730            discard $1 and renumber all the other variables. "shift N" will
731            shift N arguments at once.
733    $#
734            contains the number of arguments that were set (not including $0).
736    $*
737            contains all of the arguments in a single string, with one space
738            separating them.
740    $@
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
756     1: #!/bin/sh
757     2: #
758     3: # Check positional argument handling
759     4: echo "Number of arguments: $#"
760     5: echo "\$0 = $0"
761     6:
762     7: echo "Loop over \$*"
763     8: for a in $*; do
764     9:    echo \"$a\"
765    10: done
766    11:
767    12: echo "Loop over \"\$@\""
768    13: for a in "$@"; do
769    14:    echo \"$a\"
770    15: done
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
781     1: #!/bin/sh
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 '*'
785     5: set -o noglob
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
789     9: echo $5
791    Example: pickrandom display, text
792    Selects a random file from a directory. Uses the ksh RANDOM feature.
794     1: #!/bin/ksh
795     2:
796     3: # Select a random image from the background logo collection
797     4: # This could be used to configure a screen saver, for example.
798     5: #
799     6: # This works even if the filenames contain spaces.
800     7:
801     8: # switch to the logos directory to avoid long paths
802     9: logos=/afs/northstar/common/usr/lib/X11/logos/backgrounds
803    10: cd $logos
804    11:
805    12: # '*' is a filename wildcard to match all files in the current directory
806    13: set *
807    14:
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 % $#))
811    18:
812    19: # Output the resulting first argument
813    20: echo "$logos/$1"
815                                                                          (12)
817                                  Shell options
819    Startup options. ksh -options scriptname
821    -x
822            echo line to stderr before executing it
824    -n
825            read commands and check for syntax errors, but do not execute.
827    -a
828            all variables are automatically exported
830    -f
831            disable wildcard filename expansion (globbing)
833    set -x
834            Set an option within a shell script
836    $-
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.
843                                                                          (13)
845                               Command Substitution
847   sh syntax
849    `command`
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.
856   ksh/bash syntax
858    $(command)
859            This syntax is functionally the same as backticks, but commands
860            can be more easily nested.
862    $(<file)
863            This is equivalent to `cat file`, but implemented internally for
864            efficiency.
866    Example: ex3 display, text
868     1: #!/bin/ksh
869     2:
870     3: echo Today is `date`
871     4:
872     5: file=/etc/hosts
873     6: echo The file $file has $(wc -l < $file) lines
874     7:
875     8: hostname -s > myhostname
876     9: echo This system has host name $(<myhostname)
878                                                                          (14)
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.
886 Output redirection
888    > filename
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
895              End of File status.
897    >> filename
898            Standard ouput is appended to the named file. The file is created
899            if it does not exist.
901    >| filename
902            Output redirect, and override the noclobber option, if set.
904 Input redirection
906    < filename
907            Standard input (file descriptor 0) is redirected to the named
908            file. The file must already exist.
910 Command pipelines
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.
929                                                                          (15)
931                                 Input and Output
933    Shell scripts can generate output directly or read input into variables
934    using the following commands:
936   Script output
938    echo
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          
948                                    versions)                                  
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.
956                 -n
957                         suppress newline
959    print (ksh internal)
960            Print arguments, separated by spaces, and terminated by a newline,
961            to stdout. Print observes the same escape conventions as echo.
963                 -n
964                         suppress newline
966                 -r
967                         raw mode - ignore \-escape conventions
969                 -R
970                         raw mode - ignore \-escape conventions and -options
971                         except -n.
973   Script input
975    read var1 var2 rest
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
980            following line.
982                 -r
983                         raw mode - ignore \-escape conventions
985    Example: ex4a display, text
987     1: #!/bin/sh
988     2: echo "Testing interactive user input: enter some keystrokes and press return"
989     3: read x more
990     4: echo "First word was \"$x\""
991     5: echo "Rest of the line (if any) was \"$more\""
993                                                                          (16)
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
1003    convention.
1005   File tests
1007    -e file
1008            True if file exists (can be of any type).
1010    -f file
1011            True if file exists and is an ordinary file.
1013    -d file
1014            True if file exists and is a directory.
1016    -r file
1017            True if file exists and is readable
1018            Similarly, -w = writable, -x = executable, -L = is a symlink.
1020    -s file
1021            True if file exists and has size greater than zero
1023    -t filedescriptor
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
1030    -n "string"
1031            true if string has non-zero length
1033    -z "string"
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
1039              string.
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.
1046    $variable = text
1047            True if $variable matches text.
1049    $variable < text
1050            True if $variable comes before (lexically) text
1051            Similarly, > = comes after
1053                                                                          (17)
1055              More conditional tests for [...] and [[...]] commands
1057   Arithmetic tests
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
1064            number.
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)
1070    $variable = pattern
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.
1079    file1 -nt file2
1080            True if file1 is newer than file2.
1081            Similarly -ot = older than
1083    file1 -ef file2
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.
1101    Examples:
1103  if [[  -x /usr/local/bin/lserve && \
1104         -w /var/logs/lserve.log ]]; then
1105     /usr/local/bin/lserve >> /var/logs/lserve.log &
1106  fi
1108  pwent=`grep '^richard:' /etc/passwd`
1109  if [ -z "$pwent" ]; then
1110     echo richard not found
1111  fi
1113                                                                          (18)
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
1126    list && list
1127            Execute the first list. If true (success), execute the second one.
1129    list || list
1130            Execute the first list. If false (failure), execute the second
1131            one.
1133            Example:
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.
1141              Example:
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"
1149            lists are optional.
1151            Example:
1153  if [ -r $myfile ]
1154  then
1155     cat $myfile
1156  else
1157     echo $myfile not readable
1158  fi
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
1171     1: #!/bin/ksh
1172     2: count=0
1173     3: max=10
1174     4: while [[ $count -lt $max ]]
1175     5: do
1176     6:   echo $count
1177     7:   count=$((count + 1))
1178     8: done
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.
1186            Example:
1188  for file in *.dat
1189  do
1190      echo Processing $file
1191  done
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.
1209     1: #!/bin/sh
1210     2:
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.
1215     7:
1216     8: line="TEST"
1217     9: save=
1218    10:
1219    11: if [ -z "$1" ]; then
1220    12:    echo "Usage: $0 filename"
1221    13: else
1222    14:    if [ -r $1 ]; then
1223    15:       while read line; do
1224    16:          echo "$line"
1225    17:          save=$line
1226    18:       done < $1
1227    19:    fi
1228    20: fi
1229    21: echo "End value of \$line is $line"
1230    22: echo "End value of \$save is $save"
1232                                                                          (19)
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:
1247                   ?(pattern-list)
1248                           Optionally matches any one of the given patterns.
1250                   *(pattern-list)
1251                           Matches zero or more occurrences of the given
1252                           patterns.
1254                   +(pattern-list)
1255                           Matches one or more occurrences of the given
1256                           patterns.
1258                   @(pattern-list)
1259                           Matches exactly one of the given patterns.
1261                   !(pattern-list)
1262                           Matches anything, except one of the given patterns.
1264            Example:
1266      case $filename in
1267      *.dat)
1268          echo Processing a .dat file
1269          ;;
1270      *.sas)
1271          echo Processing a .sas file
1272          ;;
1273      *)
1274          # catch anything else that doesn't match patterns
1275          echo "Don't know how to deal with $filename"
1276          ;;
1277      esac
1279   Miscellaneous flow control and subshells
1281 break [n]
1282         Break out of the current (or n'th) enclosing loop. Control jumps to
1283         the next statement after the loop
1285 continue [n];
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.
1290 . filename
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).
1301                                                                          (20)
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
1308         a string.
1310         Use case with a pattern:
1311                 case $var in
1312                 /*) echo "starts with /" ;;
1313                 Works in all shells, and uses no extra processes
1315         Use `cut`:
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"
1325                 likes this one.
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
1349                                                                          (21)
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.
1357         eval args
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.
1363  netdev=NETDEV_
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
1370         exec command args
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.
1375         :
1376                 The line is variable-expanded, but otherwise treated as a
1377                 comment. Sometimes used as a synonym for "true" in a loop.
1379  while :; do
1380    # this loop will go forever until broken by
1381    # a conditional test inside, or a signal
1382  done
1384         unset var ...
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:
1394                      -L[n]
1395                              Left justify and remove leading blanks. The
1396                              variable always has length n if specified.
1398                      -R[n]
1399                              Right justify and fill with leading blanks. The
1400                              variable always has length n if specified.
1402                      -l
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
1406                              -i.
1408                        -Z[n]
1409                                As for -R, but fill with zeroes if the value
1410                                is a number
1412                        -i
1413                                Lower-case convert the named variables
1415                        -u
1416                                Upper-case convert the named variables
1418                        -r
1419                                Mark the variables as readonly
1421                        -x
1422                                Export the named variables to the enviroment
1424                        -ft
1425                                The variables are taken as function names.
1426                                Turn on execution tracing.
1428                                                                          (22)
1430                      Manipulating Variables (ksh/bash only)
1432 Text variables
1434         The pattern in the following uses the same wildcards as for filename
1435         matching.
1437         ${#var}
1438                 returns the length of $var in characters
1440         ${var%pattern}
1441                 removes the shortest suffix of $var patching pattern
1443         ${var%%pattern}
1444                 removes the longest suffix of $var patching pattern
1446         ${var#pattern}
1447                 removes the shortest prefix of $var patching pattern
1449         ${var##pattern}
1450                 removes the longest prefix of $var patching pattern
1452 Numeric variables
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).
1462         Examples
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
1468                 basename)
1470         path=${datapath%/*}
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)
1475         i=$((i+1))
1476                 often used in while loops
1478                                                                          (23)
1480                                 Shell Functions
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.
1490   Defining functions
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
1496                 namespace.
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
1502                 multiple scripts.
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.
1518         Example:
1520  die()
1522     # Print an error message and exit with given status
1523     # call as: die status "message" ["message" ...]
1524     exitstat=$1; shift
1525     for i in "$@"; do
1526        print -R "$i"
1527     done
1528     exit $exitstat
1531   Calling functions.
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).
1540         Example:
1542  [ -w $filename ] || \
1543    die 1 "$file not writeable" "check permissions"
1545         Example: Backgrounded function call. ex12 display, text
1547     1: #!/bin/sh
1548     2:
1549     3: background()
1550     4: {
1551     5:    sleep 10
1552     6:    echo "Background"
1553     7:    sleep 10
1554     8:    # Function will return here - if backgrounded, the subprocess will exit.
1555     9: }
1556    10:
1557    11: echo "ps before background function"
1558    12: ps
1559    13: background &
1560    14: echo "My PID=$$"
1561    15: echo "Background function PID=$!"
1562    16: echo "ps after background function"
1563    17: ps
1564    18: exit 0
1566         Example:
1568  vprint()
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.
1573     level=$1; shift
1574     if [[ $level -le $verbosity ]]; then
1575        print -R $*
1576     fi
1579  verbosity=2
1580  vprint 1 This message will appear
1581  vprint 3 This only appears if verbosity is 3 or higher
1583   Reuseable functions
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.
1596                                                                          (24)
1598                                   Advanced 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
1613                 current shell.
1615         exec n>outfile
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
1618                 print -u.
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.
1625         >&n
1626                 standard output is moved to whatever file descriptor n is
1627                 currently pointing to
1629         <&n
1630                 standard input is moved to whatever file descriptor n is
1631                 currently pointing to
1633         n>file
1634                 file descriptor n is opened for writing on the named file.
1636         n>&1
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
1652         open/append/close):
1654         print -u n args
1655                 print to file descriptor n.
1657         -p
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.
1667         -p
1668                 read from the pipe to a coprocess (opened by |&)
1670   Closing file handles
1672         <&-
1673                 standard input is explicitly closed
1675         >&-
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)
1686   "Here" documents
1688         << [-]string
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
1695     1: #!/bin/sh
1696     2: echo "Example of unquoted here document, with variable and command substitution"
1697     3:
1698     4: cat <<EOF
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`
1703     9: EOF
1704    10: echo
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`
1712    18: EndOfInput
1714         Example: duplex display, text
1716     1: #!/bin/sh
1717     2: # Add in the magic postscript preface to perform
1718     3: # duplex printer control for Xerox docuprint.
1719     4:
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.
1722     7:
1723     8: ## (
1724     9: cat << EOP
1725    10: %!PS
1726    11: %%BeginFeature: *Duplex DuplexTumble
1727    12: <</Duplex true /Tumble false>> setpagedevice
1728    13: %%EndFeature
1729    14: EOP
1730    15: cat "$@"
1731    16: ## ) | lpr
1733                                                                          (25)
1735                                 Wizard Level I/O
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.
1741         ex13: display, text
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
1746  exit 99
1748   Pass stderr of a command into a pipeline for further processing
1750         Example: ex14 display, text
1752         exec 3>&1
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
1760         expect.
1762     1: #!/bin/sh
1763     2: # Example 14
1764     3: # Take stderr from a command and pass it into a pipe
1765     4: # for further processing.
1766     5:
1767     6: # Uses ex13.sh to generate some output to stderr
1768     7: # stdout of ex13 is processed normally
1769     8:
1770     9: # Save a copy of original stdout
1771    10: exec 3>&1
1772    11:
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
1777    16:
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
1785         exec 3>&1
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.
1801     1: #!/bin/sh
1802     2: # Example 15
1803     3:
1804     4: # Uses ex13.sh to generate some output and give us an
1805     5: # exit status to capture.
1806     6:
1807     7: # Get the exit status of ex13 into $ex13stat. 
1808     8: # stdout of ex13 is processed normally
1809     9:
1810    10: # Save a copy of stdout
1811    11: exec 3>&1
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`
1822    22:
1823    23: echo Last command status=$?
1824    24: echo ex13stat=$ex13stat
1825    25:
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
1829    29: exec 3>&1
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
1839         exec 3>&1
1840         ex13stat=`((./ex13.sh 2>&1 1>&3 3>&- 4>&- ; echo $? >&4) | \
1841         sed s/err/ERR/ 1>&2 3>&- 4>&- ) 4>&1`
1843     1: #!/bin/sh
1844     2: # Example 16
1845     3:
1846     4: # Uses ex13.sh to generate some output and give us an
1847     5: # exit status to capture.
1848     6:
1849     7: # Get the exit status of ex13 into ex13stat.
1850     8: # stderr of ex13 is processed by the pipe, stdout
1851     9: # is left alone.
1852    10:
1853    11: # Save a copy of stdout
1854    12: exec 3>&1
1855    13:
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`
1859    17:
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)
1863    21:
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
1867    25:
1868    26: # Close the extra descriptors before running the commands
1869    27: exec 3>&1
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`
1872    30:
1873    31: echo Last command status=$?
1874    32: echo ex13stat=$ex13stat
1875    33:
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.
1882                                                                          (26)
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.
1893         command &
1894                 Start command as a background process. Control returns
1895                 immediately to the shell.
1897         bgpid=$!
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
1901                 (kill -HUP $bgpid).
1903   ksh coprocesses
1905         Coprocesses are a way of starting a separate process which runs
1906         asychronously, but has stdin/stdout connected to the parent script
1907         via pipes.
1909         command |&
1910                 Start a coprocess with a 2-way pipe to it
1912         read -p var
1913                 Read from the pipe to the coprocess, instead of standard
1914                 input
1916         print -p args
1917                 Write to the pipe connected to the coprocess, instead of
1918                 standard output
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.
1924         exec <&p
1925                 The input from the coprocess is moved to standard input
1927         exec >&p
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
1933         as
1934         script | tee outfile
1936     1: #!/bin/ksh
1937     2:
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.
1941     6:
1942     7: if [[ -t 1 ]] ; then
1943     8:   # Only do this if fd 1 (stdout) is still connected
1944     9:   # to a terminal
1945    10:
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
1949    14:
1950    15:   tee $0.out >/dev/tty |&
1951    16:
1952    17:   # Our stdout all goes into this coprocess
1953    18:   exec 1>&p
1954    19: fi
1955    20:
1956    21: # Now generate some output
1957    22: print "User activity snapshot on $(hostname) at $(date)"
1958    23: print
1959    24: who
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.
1965     1: #!/bin/ksh
1966     2: # This example uses a locally written tool for Dartmouth Name Directory lookups
1967     3:
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 |&
1971     7:
1972     8: # move the input/output streams so we
1973     9: # can use other coprocesses too
1974    10: exec 4>&p
1975    11: exec 5<&p
1976    12:
1977    13: echo "Name file contents:"
1978    14: cat namefile
1979    15: echo
1980    16:
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"
1989    25:     ;;
1990    26:   *no\ match*)
1991    27:     # handle case where the name wasn't found
1992    28:     print "No matches to \"$uname\" in DND"
1993    29:     ;;
1994    30:   *)
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\""
1998    34:     ;;
1999    35:   esac
2000    36:   sleep 2
2001    37: done < namefile
2002    38:
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.
2006    42: exec 4>&-
2008                                                                          (27)
2010                                 Variable arrays
2012         Both ksh and bash implement arrays of variables, but in somewhat
2013         different ways.
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
2020         (bash).
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
2031     1: #!/bin/bash
2032     2: # $Header: $
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.
2035     5: #
2036     6: # Options:
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
2040    10:
2041    11: hextodec()
2042    12: {
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}))
2045    15: }
2046    16:
2047    17: hostlookup()
2048    18: {
2049    19:    # Convert a decimal IP to hostname - calls 'host' each time
2050    20:    hostname=$(host $1)
2051    21:    case $hostname in
2052    22:    *\ not\ found*)
2053    23:       # Just echo the address we tried to look up
2054    24:       echo "$1"
2055    25:       ;;
2056    26:    *)
2057    27:       # The result is word 5.  Lower-case it for consistency
2058    28:       set $hostname
2059    29:       echo "$5" | tr 'A-Z' 'a-z'
2060    30:       ;;
2061    31:    esac
2062    32: }
2063    33:
2064    34: # Options
2065    35: iptranslate=0
2066    36: gethostnames=0
2067    37: filter=cat
2068    38: while getopts ihu: o ; do
2069    39:    case $o in
2070    40:    i) iptranslate=1 ;;
2071    41:    h) gethostnames=1; iptranslate=1 ;;
2072    42:    u) filter="grep $OPTARG" ;;
2073    43:    esac
2074    44: done
2075    45: shift $(($OPTIND-1))
2076    46:
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}')
2081    51:
2082    52: # If we want to filter usernames, it is more efficient to do it inline, before sorting, translation and hostname lookups
2083    53:
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
2087    57:
2088    58: (
2089    59: for dbserver in $serverlist; do
2090    60:    bos getlog -server $dbserver -file /usr/afs/logs/AuthLog
2091    61: done
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
2096    66:       # Ugly!
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.
2099    69:       case $line in
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)
2109    79:             index=$ipdec
2110    80:             if [[ -z "${hostnames[$index]}" ]]; then
2111    81:                hostnames[$index]="$(hostlookup $(hextodec $iphex))"
2112    82:             fi
2113    83:             echo "$frontpart from ${hostnames[$index]}"
2114    84:          else
2115    85:             echo "$frontpart from $(hextodec $iphex)"
2116    86:          fi
2117    87:          ;;
2118    88:       *)
2119    89:          echo "$line"
2120    90:          ;;
2121    91:       esac
2122    92:    else
2123    93:       # No ip translation, just echo the whole line
2124    94:       echo "$line"
2125    95:    fi  
2126    96: done
2127    97:
2129                                                                          (28)
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
2141         process with kill.
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:
2153                  EXIT
2154                          the handler is called when the function exits, or
2155                          when the whole script exits. The exit signal has
2156                          value 0.
2158                  ERR (ksh)
2159                          the handler is called when any command has a
2160                          non-zero exit status
2162                  DEBUG (ksh)
2163                          the handler is called after each command.
2165         Example: ex8 display, text
2167     1: #!/bin/bash
2168     2: # Try this under bash, ksh and sh
2169     3:
2170     4: trap huphandler  HUP
2171     5: trap ''          QUIT
2172     6: trap exithandler TERM INT
2173     7:
2174     8: huphandler()
2175     9: {
2176    10:    echo 'Received SIGHUP'
2177    11:    echo "continuing"
2178    12: }
2179    13:
2180    14: exithandler()
2181    15: {
2182    16:    echo 'Received SIGTERM or SIGINT'
2183    17:    exit 1
2184    18: }
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
2189    23: seconds=0
2190    24: while : ; do
2191    25: # while true; do
2192    26:    sleep 5
2193    27:    seconds=$((seconds + 5))
2194    28:    echo -n "$SECONDS $seconds - "
2195    29: done
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.
2201                                                                          (29)
2203                         Security issues in shell scripts
2205         Shell scripts are often used by system administrators and are run as
2206         a priviledged user.
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
2213               like sudo instead.
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.
2227               Example:
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.
2237               Example:
2239  (umask 077 && mkdir /tmp/tempdir.$$) || exit 1
2241               or (deluxe version)
2243  tmp=${TMPDIR:-/tmp}
2244  tmp=$tmp/tempdir.$RANDOM.$RANDOM.$RANDOM.$$
2245  (umask 077 && mkdir $tmp) || {
2246      echo "Could not create temporary directory" 1>&2
2247      exit 1
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
2257                * contents of files
2258                * data piped from other programs
2259                * file names. Output of filename generation with wildcards, or
2260                  directly from ls or find
2262         Example:
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
2267           names:
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 \'" ?*;
2274  protect_filenames()
2276     sed -es/\\\\/\\\\\\\\/g \
2277         -es/\\\'/\\\\\'/g   \
2278         -es/\\\"/\\\\\"/g   \
2279         -es/\\\;/\\\\\;/g   \
2280         -es/\\\?/\\\\\?/g   \
2281         -es/\\\*/\\\\\*/g   \
2282         -es/\\\ /\\\\\ /g
2285           If using GNU find and xargs, there is a much cleaner option to
2286           null-terminate generated pathnames.
2288                                                                          (30)
2290                                      Style
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
2299             revision notes
2300           * Use a revision control system for complex scripts with a long
2301             lifetime
2302           * Assume your script will have a long lifetime unless you are
2303             certain it won't
2304           * Document any non-standard external utilities which your script
2305             needs
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
2310             toolkit philosophy)
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
2315             utilities
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.
2319           * Test (a lot)
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.
2329                                                                          (31)
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
2339         notes.
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
2346             programs.
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.
2354             (Blinn)
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
2374                                                                          (32)
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
2385         named.
2387   Listing, copying and moving files and directories
2389         ls *
2390                 list contents of a directory, or list details of files and
2391                 directories.
2393         mkdir; rmdir *
2394                 Make and Remove directories.
2396         rm; cp; mv *
2397                 Remove (delete), Copy and Move (rename) files and directories
2399         touch *
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
2405                   occurred.
2407         tee
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
2414         echo *
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.
2424         cat *
2425                 Copy and concatenate files; display contents of a file
2427         head, tail *
2428                 Display the beginning of a file, or the end of it.
2430         cut
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.
2434         wc
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
2445         sort *
2446                 Sort data alphabetically or numerically.
2448         grep *
2449                 Search a file for lines containing character patterns. The
2450                 patterns can be simple fixed text, or very complex regular
2451                 expressions.
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.
2457         uniq *
2458                 Remove duplicate lines, and generate a count of repeated
2459                 lines.
2461         wc *
2462                 Count lines, words and characters in a file.
2464   System information (users, processes, time)
2466         date *
2467                 Display the current date and time (flexible format). Useful
2468                 for conditional execution based on time, and for timestamping
2469                 output.
2471         ps *
2472                 List the to a running processes.
2474         kill *
2475                 Send a signal (interrupt) to a running process.
2477         id
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)
2482         who
2483                 Display who is logged on the system, and from where they
2484                 logged in.
2486         uname *
2487                 Display information about the system, OS version, hardware
2488                 architecture etc.
2490         mail *
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.
2496         logger
2497                 Place a message in the central system logging facility.
2498                 Scripts can submit messages with all the facilities available
2499                 to compiled programs.
2501         hostname
2502                 Display the hostname of the current host - usful to keep
2503                 track of where your programs are running
2505   Conditional tests
2507         test; [ *
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:
2512                 if [ -w logfile ]
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
2520                   syntax.
2522   Stream Editing
2524         awk *
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').
2533         sed *
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.
2543         tr
2544                 Transliterate - perform very simple single-character edits on
2545                 a file.
2547   Finding and comparing files
2549         find *
2550                 Search the filesystem and find files matching certain
2551                 criteria (name pattern, age, owner, size, last modified etc.)
2553         xargs *
2554                 Apply multiple filename arguments to a named command and run
2555                 it.
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
2563                   individually.
2565         diff *
2566                 Compare two files and list the differences between them.
2568         basename pathname
2569                 Returns the base filename portion of the named pathname,
2570                 stripping off all the directories
2572         dirname pathname
2573                 Returns the directory portion of the named pathname,
2574                 stripping off the filename
2576   Arithmetic and String Manipulation
2578         expr *
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.
2583                 expr 2 + 1
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\.*'
2590         dc
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
2596         bc
2597                 A preprocessor for dc which provides infix notation and a
2598                 C-like syntax for expressions and functions.
2600   Merging files
2602         paste
2603                 Merge lines from multiple files into tab-delimited columns.
2605         join
2606                 Perform a join (in the relational database sense) of lines in
2607                 two sorted input files.
2609                                                                          (33)
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.
2621   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
2627             Robbins. More info
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
2642             Edition). More info
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
2656             Intuitive site
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
2660             et al. More info
2662   Online Resources
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
2673             general
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
2684             available.
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