%\documentclass[colorBG,slideColor,troispoints,pdf]{prosper}
%\documentclass[colorBG,total,slideColor,pdf]{prosper}
\documentclass[total,pdf]{prosper}
%\documentclass[colorBG,slideColor,ps]{prosper}

\usepackage[toc,highlight,vsimple]{HA-prosper}% DO NOT EDIT---WILL BE OVERWRITTEN

\usepackage{alltt,key,xr,cols,rcs,acro,nick,%
  graphicx,varioref,explanation,booktabs,amssymb}

\RCS $Revision: 1.12 $

% Copyright (c) 2004 by Nick Urbanik <nicku(at)nicku.org>.
% This material may be distributed only subject to the terms and
% conditions set forth in the Open Publication License, v1.0 or later
% (the latest version is presently available at
% http://www.opencontent.org/openpub/).
                                                                                % For Prosper sizing: see
% http://sourceforge.net/mailarchive/forum.php?thread_id=1373415&forum_id=4400
% export GS_OPTIONS="-sPAPERSIZE=a4"

\externaldocument[lt-]%
{../../linux_training-plus-config-files-ossi/build/masterfile}

% \usepackage[pdfpagemode=None,pdfauthor={Nick Urbanik}]{hyperref}

\renewcommand*{\bs}{\texttt{\char '134}} % Backslash `\'
\newcommand*{\labTitle}{Shell Programming---an Introduction}
\newcommand*{\subject}{Operating Systems and Systems Integration}
\newcommand*{\emphcolour}[1]{\emph{\red#1}}

\providecommand*{\RPM}{\acro{RPM}\xspace}
\providecommand*{\CD}{\acro{CD}\xspace}
% Get rid of that horrible hash mark in slide numbers in ppr-prv.cls:
\def\no{}

\title{Shell Programming---an Introduction}
%% \author{Nick Urbanik}
%% \email{nicku@nicku.org}
%% \institution{A computing department}
\slideCaption{OSSI --- Shell Programming --- ver. \RCSRevision}
\author{Nick Urbanik\\
  \email{nicku@nicku.org}\\
  \institution{A computing department}}
\subtitle{\footnotesize{}Copyright Conditions: Open Publication License (see
  \url{http://www.opencontent.org/openpub/})}%
%% \subtitle{\footnotesize{}Copyright Conditions: GNU FDL (see
%% \url{http://www.gnu.org/licenses/fdl.html})}
%%%\Logo{\includegraphics[width=15mm]{ict-logo-smaller}}
\setlength{\extrarowheight}{0pt}

\DefaultTransition{Wipe}
\TitleSlideNav{FullScreen}
\NormalSlideNav{ShowBookmarks}
\LeftFoot{OSSI --- ver. \RCSRevision}
\RightFoot{Shell Programming}

\begin{document}
\maketitle

\tsection{Intro}

%\tableofcontents

\begin{slide}{Aim}
\small
After successfully working through this exercise, You will:
\begin{itemize}
\item write simple shell scripts using \texttt{for}, \texttt{if},
  \texttt{while}, \texttt{case}, \texttt{getopts} statements;
\item write shell script functions, and be able to handle parameters;
\item understand basic regular expressions, and be able to create your
  own regular expressions;
\item understand how to execute and debug these scripts;
\item understand some simple shell scripts written by others.
\end{itemize}
\end{slide}

\begin{slide}{Why Shell Scripting?}
  
\begin{itemize}
\item Basic startup, shutdown of Linux, \UNIX systems uses large
  number of shell scripts
  \begin{itemize}
  \item understanding shell scripting important to understand and perhaps
    modify behaviour of system
  \end{itemize}
  
\item Very high level: powerful script can be very short
\item Can build, test script incrementally
\item Useful on the command line: ``one liners''
\end{itemize}
\end{slide}

\begin{slide}{Where to get more information}
  \label{sld:references}
  \begin{itemize}
  \item the Libarary has two copies of the book, \emph{Learning the Bash
    Shell}, second edition, by Cameron Newham \& Bill Rosenblatt,
    O'Reilly, 1998. 

  \item There is a free on-line book about shell programming at:
    \url{http://tldp.org/LDP/abs/html/index.html} and
    \url{http://tldp.org/LDP/abs/abs-guide.pdf}.  It has hundreds of
    pages, and is packed with \emph{examples}.

  \item The handy
    reference to shell programming is:
\begin{alltt}
$ \textbf{pinfo bash}
\end{alltt}%$
    or
\begin{alltt}
$ \textbf{man bash}
\end{alltt}%$
\item {\Large\emphcolour{IMPORTANT}:} \texttt{bash} provides simple
  on-line help for all built-in commands, e.g.,
\begin{alltt}
$ \textbf{help let}
\end{alltt}%$
  \end{itemize}
\end{slide}

\begin{slide}{The Shell is an Interpreter}
  \begin{itemize}
  \item Some languages are compiled: C, \C++, Java,\dots
  \item Some languages are interpreted: Java bytecode, Shell
  \item Shell is an interpreter: kernel does not run shell program
    directly:
    \begin{itemize}
    \item kernel runs the shell program \texttt{/bin/sh} with script
      file name as a parameter
    \item the kernel cannot execute the shell script directly, as it
      can a binary executable file that results from compiling a C program
    \end{itemize}
  \end{itemize}
\end{slide}

%\tsection{Running Scripts}

\begin{slide}{The Shebang}
  \begin{itemize}
  \item You ask the Linux kernel to execute the shell script
  \item kernel reads first two characters of the executable file
    \begin{itemize}
    \item If first 2 chars are ``\#!'' then
    \item kernel executes the name that follows, with the file name of
    the script as a parameter
    \end{itemize}
  \item Example: a file called \texttt{find.sh} has this as the first
    line:
\begin{alltt}
#! /bin/sh
\end{alltt}
  \item then kernel executes this:
\begin{alltt}
/bin/sh find.sh
\end{alltt}
\item What will happen in each case if an executable file begins with:
  \begin{itemize}
  \item 
\begin{verbatim}
#! /bin/rm
\end{verbatim}
  \item 
\begin{verbatim}
#! /bin/ls
\end{verbatim}
  \end{itemize}
\end{itemize}
\end{slide}

\begin{slide}[toc={Making Executable}]{Making the script executable}
  \label{sld:making-script-executable}
  To easily execute a script, it should:
  \begin{itemize}
  \item be on the \texttt{PATH}
  \item have execute permission.
  \end{itemize}
  How to do each of these?
  \begin{itemize}
  \item Red Hat Linux by default, includes the directory
    $\sim$\texttt{/bin} on the \texttt{PATH}, so create this
    directory, and put your scripts there:
\begin{alltt}
$ \textbf{mkdir \(\sim\)/bin}
\end{alltt}%$
  \item If your script is called \texttt{script}, then this command
    will make it executable:
\begin{alltt}
$ \textbf{chmod +x script}
\end{alltt}%$
  \end{itemize}
\end{slide}

\tsection{Quoting and Funny Chars}

\begin{slide}{Special Characters}
  \begin{itemize}
  \item Many characters are \emphcolour{special} to the shell, and have a
    particular meaning to the shell.
  \end{itemize}
  \vspace*{-1ex}
\footnotesize\setlength{\extrarowheight}{0pt}
  \begin{tabular}[t]{@{}>{\ttfamily}cll@{}}
    \toprule%
    \multicolumn{1}{c}{\textbf{Character}} & \textbf{Meaning} &
    \multicolumn{1}{c@{}}{\textbf{See slide}}\\
    \midrule%
    $\sim$ & Home directory & \S\,\ref{sld:making-script-executable}\\
    ` & Command substitution. Better: \texttt{\$(\ldots)} &
    \S\,\ref{sld:command-substitution} \\
    \# & Comment &  \\
    \$ & Variable expression & \S\,\ref{sld:variables} \\
    \& & Background Job &
    \vref{lt-sec:basic-shell-and-tools-approach-background-processes} \\
    \texttt{*} & File name matching wildcard &
    \vref{lt-sec:basic-shell-and-tools-approach-filename-generation} \\
    \verb+|+ & Pipe & \vref{lt-sec:basic-shell-and-tools-approach-pipelines} \\
    \bottomrule
  \end{tabular}
\end{slide}

\begin{slide}[toc={Special Chars---2}]{Special Characters---continued: 2}
  \footnotesize\setlength{\extrarowheight}{0pt}
  \begin{tabular}[t]{@{}>{\ttfamily}cll@{}}
    \toprule%
    \multicolumn{1}{c}{\textbf{Character}} & \textbf{Meaning} &
    \multicolumn{1}{c@{}}{\textbf{See slide}}\\
    \midrule%
    ( & Start subshell & \S\,\ref{sld:change-IFS},
    \ref{sld:vars-in-subshell}, \ref{sld:blocks} \\
    ) & End subshell &
    \S\,\ref{sld:change-IFS}, \ref{sld:vars-in-subshell}, \ref{sld:blocks} \\
    {[} & Start character set file name matching &
    \vref{lt-sec:basic-shell-and-tools-approach-pipelines} \\
    {]} & End character set file name matching &
    \vref{lt-sec:basic-shell-and-tools-approach-pipelines} \\
    \{ & Start command block & \S\,\ref{sld:blocks} \\
    ; & Command separator & \S\,\ref{sld:error-handling} \\
    \bs & Quote next character & \S\,\ref{sld:more-about-quoting} \\
    ' & Strong quote & \S\,\ref{sld:more-about-quoting} \\
    " & Weak quote & \S\,\ref{sld:more-about-quoting} \\
    \bottomrule
  \end{tabular}
\end{slide}

\begin{slide}[toc={Special Chars---3}]{Special Characters---continued: 3}
  \footnotesize\setlength{\extrarowheight}{0pt}
  \begin{tabular}[t]{@{}>{\ttfamily}cll@{}}
    \toprule%
    \multicolumn{1}{c}{\textbf{Character}} & \textbf{Meaning} &
    \multicolumn{1}{c@{}}{\textbf{See slide}}\\
    \midrule%
    \texttt{<} & Input redirect &
    \vref{lt-sec:basic-shell-and-tools-approach-input-redirection} \\
    \texttt{>} & Output redirect &
    \vref{lt-sec:basic-shell-and-tools-approach-output-redirection} \\
    \texttt{/} & Pathname directory separator & \\
    ? & Single-character match in filenames &
    \vref{lt-sec:basic-shell-and-tools-approach-filename-generation} \\
    ! & Pipline logical NOT & \S\,\ref{sld:not-operator}\\
    \meta{space or tab} & shell normally splits at white space
    & \S\ref{sld:ifs} \\
    \bottomrule
  \end{tabular}
  \par\medskip\par%
  \begin{itemize}
  \item Note that references to pages in the tables above refer to the
    modules in the workshop notes
  \end{itemize}
\end{slide}

\begin{slide}{Quoting}
\label{sld:quoting}
\begin{itemize}
\item Sometimes you want to use a special character
  \emph{literally}; i.e., without its special meaning.
\item Called \emphcolour{quoting}
\item Suppose you want to print the string: \texttt{2 * 3 > 5 is a valid
    inequality}?
\item If you did this:
\begin{alltt}
$ \textbf{echo 2 * 3 > 5 is a valid inequality}
\end{alltt}%$
the new file `\texttt{5}' is created, containing the character
`\texttt{2}', then the names of all the files in the current
directory, then the string ``\texttt{3 is a valid inequality}''.
\end{itemize}
\end{slide}

\begin{slide}{Quoting---2}
\label{sld:quoting2}
\begin{itemize}
\item To make it work, you need to protect the special characters
  `\texttt{*}' and `\texttt{>}' from the shell by quoting them.  There
  are three methods of quoting:
  \begin{itemize}
  \item Using double quotes (``weak quotes'')
  \item Using single quotes (``strong quotes'')
  \item Using a backslash in front of each special character you want
    to quote
  \end{itemize}
\item This example shows all three:
\begin{alltt}
$ \textbf{echo "2 * 3 > 5 is a valid inequality"}
$ \textbf{echo '2 * 3 > 5 is a valid inequality'}
$ \textbf{echo 2 \bs* 3 \bs> 5 is a valid inequality}
\end{alltt}%$
\end{itemize}
\end{slide}

\begin{slide}{Quoting---When to use it?}
  \begin{itemize}
  \item Use quoting when you want to pass special characters to
    another program.
  \item Examples of programs that often use special characters:
    \begin{itemize}
    \item \texttt{find}, \texttt{locate}, \texttt{grep},
      \texttt{expr}, \texttt{sed} and \texttt{echo}
    \end{itemize}
  \item Here are examples where quoting is required for the program to
  work properly:
\begin{alltt}
$ \textbf{find . -name \bs*.jpg}
$ \textbf{locate '/usr/bin/c*'}
$ \textbf{grep 'main.*(' *.c}
$ \textbf{i=$(expr i \bs* 5)}
\end{alltt}
  \end{itemize}
\end{slide}

\tsection{Variables}

\begin{slide}{True and False}
  \begin{itemize}
  \item Shell programs depend on executing external programs
  \item When any external program execution is successful, the exit
    status is zero, 0
  \item An error results in a non-zero error code
  \item To match this, in shell programming:
    \begin{itemize}
    \item The value 0 is true
    \item any non-zero value is false
    \end{itemize}
  \item This is opposite from other programming languages
  \end{itemize}
\end{slide}

\begin{slide}{Variables---1}
  \label{sld:variables}
  \begin{itemize}
  \item Variables not declared; they just appear when assigned to
  \item Assignment:
    \begin{itemize}
    \item no dollar sign
    \item no space around equals sign
    \item examples:
\begin{alltt}
$ \textbf{x=10}   # \textnormal{correct}
$ \textbf{x = 10} # \textnormal{wrong: try to execute program called ``\texttt{x}''}
\end{alltt}
    \end{itemize}
  \item Read value of variable:
    \begin{itemize}
    \item put a `\texttt{\$}' in front of variable name
    \item example:
\begin{alltt}
$ \textbf{echo "The value of x is $x"}
\end{alltt}
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}{Variables---Assignments}
  \begin{itemize}
  \item You can put multiple assignments on one line:
\begin{alltt}
i=0 j=10 k=100
\end{alltt}

  \item You can set a variable temporarily while executing a program:
\begin{alltt}
$ \textbf{echo $EDITOR}
emacsclient
$ \textbf{EDITOR=gedit crontab -e}
$ \textbf{echo $EDITOR}
emacsclient
\end{alltt}%$
  \end{itemize}
\end{slide}

\begin{slide}{Variables---Local to Script}
  \label{sld:vars-in-subshell}
  \begin{itemize}
  \item Variables disappear after a script finishes
  \item Variables created in a sub shell disappear
    \begin{itemize}
    \item parent shell cannot read variables in a sub shell
    \item example:
\begin{alltt}
$ \textbf{cat variables}
#! /bin/sh
echo $HOME
HOME=happy
echo $HOME
$ \textbf{./variables}
/home/nicku
happy
$ \textbf{echo $HOME}
/home/nicku
\end{alltt}
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}{Variables---Unsetting Them}
  \begin{itemize}
  \item You can make a variable hold the null string by assigning it
    to nothing, but it does not disappear totally:
\begin{alltt}
$ \textbf{VAR=}
$ \textbf{set | grep '^VAR'}
VAR=
\end{alltt}
\item You can make it disappear totally using
  \texttt{\textbf{\red{}unset}}:
\begin{alltt}
$ \textbf{unset VAR}
$ \textbf{set | grep '^VAR'}
\end{alltt}
  \end{itemize}
\end{slide}

\begin{slide}{Command-line Parameters}
  \begin{itemize}
  \item Command-line parameters are called \texttt{\$0}, \texttt{\$1},
    \texttt{\$2}, \ldots
  
  \item Example: when call a shell script called
  ``\texttt{shell-script}'' like this:
\begin{alltt}
$ \textbf{shell-script param1 param2 param3 param4}
\end{alltt}%$
    %\vspace*{-1ex}
    {\normalsize\setlength{\extrarowheight}{-0.5pt}%
    \begin{tabular}[t]{@{}ll@{}}
      \toprule%
      \emph{variable} & \emph{value}\\
      \midrule%
      \texttt{\$0} & \texttt{shell-script}\\
      \texttt{\$1} & \texttt{param1}\\
      \texttt{\$2} & \texttt{param2}\\
      \texttt{\$3} & \texttt{param3}\\
      \texttt{\$4} & \texttt{param4}\\
      \texttt{\$\#} & number of parameters to the program, e.g., 4\\
      \bottomrule
    \end{tabular}}
  \par\medskip\par
  \begin{itemize}
  \item Note: these variables are read-only.
  \end{itemize}
\end{itemize}
\end{slide}

\begin{slide}{Special Built-in Variables}
  \begin{itemize}
  \item Both \texttt{\$@} and \texttt{\$*} are a list of all the
    parameters.
  \item The only difference between them is when they are quoted in
    quotes---see manual page for \texttt{bash}
  \item \texttt{\$?} is exit status of last command
  \item \texttt{\$\$} is the process ID of the current shell
  \item Example shell script:
\begin{alltt}
#! /bin/sh
echo $0 is the full name of this shell script
echo first parameter is $1
echo first parameter is $2
echo first parameter is $3
echo total number of parameters is $#
echo process ID is $$
\end{alltt}%$
%$
  \end{itemize}
\end{slide}

\begin{slide}[toc={Variables: use Braces \texttt{\$\{\ldots\}}},%
  bm={Variables: use Braces \texttt{\$\{\ldots\}}}]%
  {Variables: use Braces \texttt{\red\$\{\ldots\}}}
  \begin{itemize}
  \item It's good to put braces round a variable name when getting its value
  \item Then no problem to join its value with other text:
\begin{alltt}
$ \textbf{test=123}
$ \textbf{echo $\{test\}}
123
\textbf{# No good, variable $test456 is undefined:}
$ \textbf{echo $test456}
 
$ \textbf{echo $\{test\}456}
123456
\end{alltt}%
\end{itemize}
\end{slide}

\begin{slide}[toc={After \texttt{\$9}}]%
  {Braces and Parameters after \textbf{\$9}}
  \begin{itemize}
  \item Need braces to access parameters after \texttt{\$9}:
\begin{alltt}
$ \textbf{cat paramten}
#! /bin/sh
echo $10
echo $\{10\}
$ \textbf{./paramten a b c d e f g h i j}
a0
j
\end{alltt}

\item Notice that \texttt{\$10} is the same as \texttt{\$\{1\}0}, i.e., the
first parameter ``\texttt{a}'' then the literal character zero
``\texttt{0}''
  \end{itemize}
\end{slide}

\begin{slide}{More about Quoting}
  \label{sld:more-about-quoting}
  \begin{itemize}
  \item {\mbox{}\red{}Double quotes}: \texttt{"..."} stop the special
    behaviour of all special characters, except for:
    \begin{itemize}
    \item variable interpretation (\texttt{\$})
    \item backticks (\texttt{`}) --- see slide~\ref{sld:command-substitution}
    \item the backslash (\bs)
    \end{itemize}
  \item {\mbox{}\red{}Single quotes} \texttt{'...'}:
    \begin{itemize}
    \item stop the special behaviour of \emphcolour{all} special
      characters
    \end{itemize}
  \item {\mbox{}\red{}Backslash}:
    \begin{itemize}
    \item preserves literal behaviour of character, except for
      newline; see
      slides~\S\ref{sld:conditions-combining-comparisons},
      \S\ref{sld:arithmetic-expressions-with-((...))},
      \S\ref{sld:for-statement-1}
    \item Putting ``\bs'' at the end of the line lets you continue a
    long line on more than one physical line, but the shell will treat
    it as if it were all on one line.
    \end{itemize}
  \end{itemize}
\end{slide}

\tsection{Command Substitution}

\begin{slide}[toc={Command Substitution},bm={Command Substitution}]%
  {Command Substitution --- \texttt{\red\$(...)} or \texttt{\red`...`}}
  \label{sld:command-substitution}
  \begin{itemize}
  \item Enclose command in \texttt{\red\$(...)} or backticks:%$
    \texttt{\red`...`}
  \item Means, ``{\magenta{}Execute the command in the
  \texttt{\red\$(...)}\magenta{} and put the output back here.}''
  \item Here is an example using \texttt{\textbf{\red{}expr}}:
\begin{alltt}
$ \textbf{expr 3 + 2}
5
$ \textbf{i=expr 3 + 2}    # \textnormal{error: try execute command `\texttt{3}'}
$ \textbf{i=$(expr 3 + 2)} # \textnormal{correct}
$ \textbf{i=`expr 3 + 2`}  # \textnormal{also correct}
\end{alltt}%$
  \end{itemize}
\end{slide}

\begin{slide}[toc={Example of Cmd Subst}]{Command Substitution---Example}
  \begin{itemize}
  \item We want to put the \emphcolour{output of the command} \texttt{hostname}
    into a \emph{\blue{}variable}:
\begin{alltt}
$ \textbf{hostname}
nickpc.tyict.vtc.edu.hk
$ \textbf{h=hostname}
$ \textbf{echo $h}
hostname
\end{alltt}%$
\item Oh dear, we only stored the \emph{\blue{}name} of the command, not the
  \emphcolour{output} of the command!

\item \emphcolour{Command substitution} solves the problem:
\begin{alltt}
$ \textbf{h=$(hostname)}
$ \textbf{echo $h}
nickpc.tyict.vtc.edu.hk
\end{alltt}%$
\item We put \texttt{\$(\ldots)} around the command.  You can then
  assign the output of the command.
  \end{itemize}
\end{slide}

\tsection{Conditions}

\begin{slide}[toc={Comparing Strings}]{Conditions---String Comparisons}
  \begin{itemize}
  \item All programming languages depend on \emphcolour{conditions}
    for \texttt{if} statements and for \texttt{while} loops
  \item Shell programming uses a built-in command which is either
    \texttt{test} or \texttt{[...]}
  \item Examples of \emphcolour{string} comparisons:
\begin{alltt}\scriptsize
[ "$USER" = root ]    # true if the value of $USER is "root"
[ "$USER" != root ]   # true if the value of $USER is not "root"
[ -z "$USER" ]        # true if the string "$USER" has zero length
[ string1 \bs< string2 ] # true if string1 sorts less than string2
[ string1 \bs> string2 ] # true if string1 sorts greater than string2
\end{alltt}
  \item Note that we need to quote the `\texttt{>}' and the `\texttt{<}'
    to avoid interpreting them as file redirection.
  \item \emphcolour{Note:} {\green{}the spaces after the ``[`` and
    before the ``]'' are essential.}
  \item {\mbox{}\blue{}Also spaces are \emphcolour{essential} around
      operators}
  \end{itemize}
\end{slide}

\begin{slide}[toc={Comparing Integers}]{Conditions---Integer Comparisons}
  \label{sld:test-arith}
  \begin{itemize}
  \item Examples of \emphcolour{numeric} integer comparisons:
\begin{alltt}\small
[ "$x" -eq 5 ]  # true if the value of $x is 5
[ "$x" -ne 5 ]  # true if integer $x is \emph{not} 5
[ "$x" -lt 5 ]  # true if integer $x is \(<\) 5
[ "$x" -gt 5 ]  # true if integer $x is \(>\) 5
[ "$x" -le 5 ]  # true if integer $x is \(\le\) 5
[ "$x" -ge 5 ]  # true if integer $x is \(\ge\) 5
\end{alltt}%
\item Note again that the spaces after the ``[`` and before the~``]''
  are essential.
  \item {\mbox{}\blue{}Also spaces are \emphcolour{essential} around
      operators}
  \end{itemize}
\end{slide}

\begin{slide}[toc={File Tests \& NOT}]{Conditions---File Tests, NOT Operator}
  \label{sld:not-operator}
  \begin{itemize}
  \item The shell provides many tests of information about
    \emphcolour{files}.
  \item Do \texttt{man test} to see the complete list.
  \item Some examples:
  \end{itemize}
  {\footnotesize%
\begin{alltt}
$ \textbf{[ -f file ]}   # true if file is an ordinary file
$ \textbf{[ ! -f file ]} # true if file is NOT an ordinary file
$ \textbf{[ -d file ]}   # true if file is a directory
$ \textbf{[ -u file ]}   # true if file has SUID permission
$ \textbf{[ -g file ]}   # true if file has SGID permission
$ \textbf{[ -x file ]}   # true if file exists and is executable
$ \textbf{[ -r file ]}   # true if file exists and is readable
$ \textbf{[ -w file ]}   # true if file exists and is writeable
$ \textbf{[ file1 -nt file2 ]} # true if file1 is newer than file2
\end{alltt}%$
    }
  \begin{itemize}
  \item \emphcolour{Note again:} {\green{}the spaces after the ``[`` and
    before the ``]'' are essential.}
  \item {\mbox{}\blue{}Also spaces are \emphcolour{essential} around
      operators}
  \end{itemize}
\end{slide}

\begin{slide}[toc={AND OR Conditions}]{Conditions---Combining Comparisons}
  \label{sld:conditions-combining-comparisons}
  \begin{itemize}
  \item Examples of \emphcolour{combining comparisons} with AND:
    \texttt{\red{}-a} and OR: \texttt{\red{}-o}, and
    \emphcolour{grouping} with \texttt{\bs(\ldots\bs)}
\begin{alltt}\small
# \textnormal{true if the value of \texttt{$x} is 5 AND \texttt{$USER} is not equal to root:}
[ "$x" -eq 5 -a "$USER" != root ]
# \textnormal{true if the value of \texttt{$x} is 5 OR \texttt{$USER} is not equal to \texttt{root}:}
[ "$x" -eq 5 -o "$USER" != root ]
# \textnormal{true if ( the value of \texttt{$x} is 5 OR \texttt{$USER} is not equal to \texttt{root} ) AND}
# \textnormal{(  \texttt{$y} \(>\) 7 OR  \texttt{$HOME} has the value happy )}
[ \bs( "$x" -eq 5 -o "$USER" != root \bs) -a \bs
\bs( "$y" -gt 7 -o "$HOME" = happy \bs) ]
\end{alltt}
\item Note again that {\green{}the spaces after the ``[`` and before
    the ``]'' are essential}.
  \item Do \texttt{man test} to see the information about all the operators.
  \end{itemize}
\end{slide}

\tsection{Arithmetic}

\begin{slide}{Arithmetic Assignments}
  \footnotesize
  \begin{itemize}
  \item Can do with the external program \texttt{\textbf{\red{}expr}}
    \begin{itemize}
    \item \ldots but \texttt{expr} is not so easy to use, although it
      is very standard and \emph{\green{}portable}: see \texttt{man~expr}
    \item Easier is to use the built in \texttt{\textbf{\red{}let}}
      command
      \begin{itemize}
      \item see \texttt{help let}
      \end{itemize}
    \item Examples:
      {\small
\begin{alltt}
$ \textbf{let x=1+4}
$ \textbf{let ++x}              # Now x is 6
$ \textbf{let x='1 + 4'}
$ \textbf{let 'x = 1 + 4'}
$ \textbf{let x="(2 + 3) * 5"}  # now x is 25
$ \textbf{let "x = 2 + 3 * 5"}  # now x is 17
$ \textbf{let "x += 5"}         # now x is 22
$ \textbf{let "x = x + 5"}      # now x is 27; NOTE NO $
\end{alltt}%$
    }
    %\vspace*{-2ex}
  \item Notice that you do not need to quote the special characters
    with \texttt{let}.
  \item Quote if you want to use white space.
  \item Do not put a dollar in front of variable, even on right side
  of assignment; see last example.
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}[toc=\texttt{\$((\ldots))},bm=\texttt{\$((\ldots))}]%
  {Arithmetic Expressions with \texttt{\red\$((\ldots))}}
  \label{sld:arithmetic-expressions-with-((...))}
  \begin{itemize}
  \item The shell interprets anything inside \texttt{\$((\ldots))} as
    an arithmetic expression
  \item You could calculate the number of days left in the year like
    this:
\begin{alltt}
$ \textbf{echo "There are \bs
$(( (365-$(date +%j)) / 7 )) weeks \bs
left till December 31"}
\end{alltt}%$
\item {\mbox{}\green{}No dollar sign} in front of variables in these
  arithmetic expressions.
  \end{itemize}
\end{slide}


\begin{slide}[toc=\texttt{((\ldots))},bm=\texttt{((\ldots))}]%
  {Arithmetic Conditions with \texttt{\red((\ldots))}}
  \label{sld:arithmetic-conditions-new}
  \begin{itemize}
  \item A (less portable) alternative to the arithmetic conditions in
    slide~\ref{sld:test-arith} is putting the expression in
    \texttt{((\ldots))}
  \item So you can do
\begin{alltt}
(( (3>2) && (4<=1) ))
\end{alltt}
    %\vspace*{-2ex}
    instead of
\begin{alltt}
[ \bs( 3 -gt 2 \bs) -a \bs( 4 -le 1 \bs) ]
\end{alltt}
    %\vspace*{-2.5ex}
  \item Operators that work with \texttt{let}, \texttt{\$((\ldots))}
  and \texttt{((\ldots))} include:
\begin{alltt}
++ -- **
+ - * / % << >> & | ~ ! ^
< > <= >= == !=
? :
\end{alltt}
which have \emph{exactly} the same effect as in the C programming
language
\begin{itemize}
\item except exponentiation operator \texttt{**}, i.e.,
\texttt{echo~\$((2**20))} prints the value of $2^{20}$, i.e., 1048576
  \item For details, see
\begin{alltt}
$ \textbf{help let}
\end{alltt}%$
  \end{itemize}
  \end{itemize}
\end{slide}

\tsection{Statements}

\begin{slide}[toc={\texttt{if} Statement},bm={\texttt{if} Statement}]%
  {\texttt{\red{}if} Statement}
  \label{sld:if-statement}
  \begin{itemize}
  \item Syntax:
    {\small
\begin{alltt}
if \meta{test-commands}
then
    \meta{statements-if-test-commands-1-true}
{\mbox{}\red{}elif} \meta{test-commands-2}
then
    \meta{statements-if-test-commands-2-true}
else
    \meta{statements-if-all-test-commands-false}
fi
\end{alltt}
}
  \item Example:
    {\small
\begin{verbatim}
if grep nick /etc/passwd > /dev/null 2>&1
then
    echo Nick has a local account here
else
    echo Nick has no local account here
fi
\end{verbatim}
    }
  \end{itemize}
\end{slide}

\begin{slide}[toc={\texttt{while} Statement},%
  bm={\texttt{while} Statement}]%
  {\texttt{\red{}while} Statement}
  \begin{itemize}
  \item Syntax:
    {\small
\begin{alltt}
while \meta{test-commands}
do
    \meta{loop-body-statements}
done
\end{alltt}
}
  \item Example:
    {\small
\begin{verbatim}
i=0
while [ "$i" -lt 10 ]
do
    echo -n "$i "    # -n suppresses newline.
    let "i = i + 1"  # i=$(expr $i + 1) also works
done
\end{verbatim}
    }
  \end{itemize}
\end{slide}

\begin{slide}[toc={\texttt{for} Statement},bm={\texttt{for} Statement}]%
  {\texttt{\red{}for} Statement}
  \label{sld:for-statement-1}
  \begin{itemize}
  \item Syntax:
    {
\begin{alltt}
for \meta{name} in \meta{words}
do
    \meta{loop-body-statements}
done
\end{alltt}
}
  \item Example:
{
\begin{verbatim}
for planet in Mercury Venus Earth Mars \
    Jupiter Saturn Uranus Neptune Pluto
do
    echo $planet
done
\end{verbatim}%$
  }
  \begin{itemize}
  \item The backslash ``\texttt{\bs}'' quotes the newline.  It's just
    a way of folding a long line in a shell script over two or more lines.
  \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}[toc={\texttt{for} Loops: Another Example},%
  bm={\texttt{for} Loops: Another Example}]%
  {\texttt{\red{}for} Loops: Another Example}
  \small%
  \begin{itemize}
  \item Here the shell turns \texttt{*.txt} into a list of file names
  ending in ``\texttt{.txt}'':%
  {\small%
\begin{verbatim}
for i in *.txt
do
    echo $i
    grep 'lost treasure' $i
done
\end{verbatim}
  }
\item You can leave the \texttt{in \meta{words}} out; in that case,
  \texttt{\meta{name}} is set to each parameter in turn:%
  {\small%
\begin{verbatim}
i=0
for parameter
do
    let 'i = i + 1'
    echo "parameter $i is $parameter"
done
\end{verbatim}
  }
  \end{itemize}
\end{slide}

\begin{slide}[toc={\texttt{for (( ; ; ))}},bm={\texttt{for (( ; ; ))}}]%
  {\texttt{\red{}for} Loops: second, C-like syntax}
  \begin{itemize}
  \item There is a second (less frequently used, and less portable)
    C-like \texttt{\textbf{\red{}for}} loop syntax:%
    {\small%
\begin{alltt}
for (( \meta{expr1} ; \meta{expr2} ; \meta{expr3} ))
do
    \meta{loop-body-statements}
done
\end{alltt}
    }
    %\vspace*{-3ex}
  \item Rules: same as for arithmetic conditions---see
    slide~\ref{sld:arithmetic-conditions-new}
  \item Example:
{\small%
\begin{verbatim}
for (( i = 0; i < 10; ++i ))
do
    echo $i
done
\end{verbatim}%$
  }
    \end{itemize}
\end{slide}

\begin{slide}[toc={\texttt{break} and \texttt{continue}},%
  bm=={\texttt{break} and \texttt{continue}}]%
  {\texttt{\red{}break} and \texttt{\red{}continue}}
  \begin{itemize}
  \item Use inside a loop
  \item Work like they do in C
  \item \texttt{\textbf{\red{}break}} terminates the innermost loop;
    execution goes on after the loop
  \item \texttt{\textbf{\red{}continue}} will skip the rest of the
    body of the loop, and resume execution on the next itteration of
    the loop.
  \end{itemize}
\end{slide}

\begin{slide}[toc={Blocks: \texttt{\{\ldots\}}},bm={Blocks: \texttt{\{\ldots\}}}]%
  {Blocks: \texttt{{\red\{}\ldots{\red\}}}}
  \label{sld:blocks}
  \begin{itemize}
  \item A \emphcolour{subshell} is one way of grouping commands
    together, but it starts a new process, and any variable changes
    are localised
  \item An alternative is to group commands into a \emphcolour{block},
    enclosing a set of commands in braces:
    \texttt{{\red\{}\ldots{\red\}}}
  \item Useful for grouping commands for \emphcolour{file input} or
    \emphcolour{output}
    \begin{itemize}
    \item \ldots\,though variables are not localised
    \end{itemize}
    %(see
    %slide~\ref{sld:grouping-for-file-io}).
  \item See next slide for another application.
  \end{itemize}
\end{slide}

\begin{slide}[toc={Flow Control: \texttt{\textbar\textbar} \texttt{\&\&}},%
  bm={Flow Control: \texttt{\textbar\textbar} \texttt{\&\&}}]%
  {Error Handling: \texttt{\red\textbar\textbar}, \texttt{\red\&\&}
    and \texttt{\red{}exit}}
  \label{sld:error-handling}
  \begin{itemize}
  \item Suppose we want the user to provide exactly two parameters, and
    exit otherwise
  \item A common method of handling this is something like:%
    {\footnotesize%
\begin{alltt}
\red[ $# -eq 2 ] || \{ echo "Need two parameters"; exit 1; \}
\end{alltt}%$
    }%
    %\vspace*{-2.5ex}
  \item Read this as ``the number of parameters is two OR exit''
  \item Works because this logical OR uses short-circuit Boolean
    evaluation; the second statement is executed only if the first
    fails (is false)
  \item Logical AND ``\texttt{\&\&}'' can be used in the same way; the
    second statement will be executed only if the first is successful
    (true)
  \item A note about blocks: must have semicolon ``\texttt{;}'' or
    newline at end of last statement before closing brace
  \end{itemize}
\end{slide}

\tsection{Input \& Output}

\begin{slide}[toc={Output: \texttt{echo} and \texttt{printf}},%
  bm={Output: \texttt{echo} and \texttt{printf}}]%
  {Output: \texttt{\red{}echo} and \texttt{\red{}printf}}
  \begin{itemize}
  \item To perform output, use \texttt{\red{}echo}, or for more formatting,
    \texttt{\textbf{\red{}printf}}.
  \item Use \texttt{echo -n} to print no newline at end.
  \item Just \texttt{echo} by itself prints a newline
  \item \texttt{printf} works the same as in the C programming
    language, except no parentheses or commas:
\begin{alltt}
$ \textbf{printf "%16s\bs{}t%8d\bs{}n" $my_string $my_number}
\end{alltt}%$'"
  \item Do \texttt{man printf} (or look it up in the \texttt{bash}
    manual page) to read all about it.
  \end{itemize}
\end{slide}

\begin{slide}[toc={Input: the \texttt{read} Command},%
  bm={Input: the \texttt{read} Command}]%
  {Input: the \texttt{\red{}read} Command}
  \begin{itemize}
  \item For input, use the built-in shell command \texttt{\red{}\textbf{read}}
  \item \texttt{read} reads standard input and puts the result into
    one or more variables
  \item If use one variable, variable holds the whole line
  \item Syntax:
\begin{alltt}
read \meta{var1}\ldots
\end{alltt}
    %\vspace*{-3ex}
  \item Often used with a \texttt{while} loop like this:
\begin{alltt}
while read var1 var2
do
    # do something with $var1 and $var2
done
\end{alltt}
    %\vspace*{-3ex}
  \item Loop terminates when reach end of file
  \item To prompt and read a value from a user, you could do:
\begin{verbatim}
while [ -z "$value" ]; do
    echo -n "Enter a value: "
    read value
done
# Now do something with $value
\end{verbatim}
  \end{itemize}
\end{slide}

\begin{slide}[toc={Split with \texttt{set}},bm={Split with \texttt{set}}]%
  {\texttt{\red{}set}: Splitting a Multi-Word Variable}
  \begin{itemize}
  \item Sometimes may want to split a multi-word variable into
    single-word variables
  \item \texttt{read} won't work like this:
\begin{alltt}
MY_FILE_INFO=$(ls -lR | grep $file)
# \ldots
echo ${MY_FILE_INFO} | read perms links \bs 
user group size month day time filename
\end{alltt}%$
%\vspace*{-2ex}
  \item Use the builtin command \texttt\textbf{\red{set}} instead:
\begin{alltt}
MY_FILE_INFO=$(ls -lR | grep $file)
# \ldots
set ${MY_FILE_INFO}
perms=$1 links=$2 user=$3 group=$4 size=$5
month=$6 day=$7 time=$8 filename=$9
\end{alltt}
  \end{itemize}
\end{slide}

\begin{slide}[toc={More about \texttt{set}, and \texttt{IFS}}]%
  {More about \texttt{set}, and \texttt{IFS}}
  \label{sld:ifs}
  \begin{itemize}
  \item \texttt{set} splits its arguments into pieces (usually) at
    whitespace
  \item It sets the first value as \texttt{\$1}, the second as
    \texttt{\$2}, and so on.
  \item Note that you can change how \texttt{set} and the shell splits
    things up by changing the value of a special variable called
    \texttt{\red{}IFS}
  \item \texttt{IFS} stands for \emphcolour{Internal Field Separator}
  \item Normally the value of \texttt{IFS} is the string
    ``\meta{space}\meta{tab}\meta{newline}''
  \item Next slide shows how changing \texttt{IFS} to a colon let us
    easily split the \texttt{PATH} into separate
    directories:\hfill$\rightsquigarrow$~{\tiny next~slide}
  \end{itemize}
\end{slide}

\begin{slide}[toc={Example: Changing \texttt{IFS}},%
  bm={Example: Changing \texttt{IFS}}]%
  {Example: Changing \texttt{\red{}IFS}}
  \label{sld:change-IFS}
    \begin{itemize}
    \item Notice that here, I make the change to \texttt{IFS} in a
    subshell.  I have simply typed the loop at the prompt.
  \item As I said in slide~\ref{sld:vars-in-subshell}, changes in
    a subshell are local to the subshell:
    {\footnotesize%
\begin{alltt}
$ \textbf{echo $PATH}
/usr/bin:/bin:/usr/X11R6/bin:/home/nicku/bin
$ \textbf{(IFS=:}
> \textbf{for dir in $PATH}
> \textbf{do}
> \textbf{    echo $dir}
> \textbf{done}
> \textbf{)}
/usr/bin
/bin
/usr/X11R6/bin
/home/nicku/bin
\end{alltt}%$
  }
  \end{itemize}
\end{slide}

\tsection{Command-line Parameters}

\begin{slide}[toc={\texttt{case} Statement},bm={\texttt{case} Statement}]%
  {\texttt{\red{}case} Statement}
  \begin{itemize}
  \item Similar to the \texttt{switch} statement in C, but more
    useful and more general
  \item Uses pattern matching against a string to decide on an
    action to take
  \item Syntax:
\begin{alltt}
case \meta{expression} in
    \meta{pattern1} )
        \meta{statements} ;;
    \meta{pattern2} )
        \meta{statements} ;;
    \ldots
esac
\end{alltt}
  \end{itemize}
\end{slide}

\begin{slide}{\texttt{case} Statement: Example}
  \begin{itemize}
  \item This example code runs the appropriate program on a graphics
    file, depending on the file extension, to convert the file
    to another format:
  \end{itemize}
  %\vspace*{-2.5ex}
\begin{alltt}
case $filename in
    *.tif)
        tifftopnm $filename > $ppmfile
        ;;
    *.jpg)
        tjpeg $filename > $ppmfile
        ;;
    *)
        echo -n "Sorry, cannot handle this "
        echo "graphics format"
        ;;
esac
\end{alltt}%$
\end{slide}

\begin{slide}[toc={\texttt{shift} Up},bm={\texttt{shift} Up}]%
  {\texttt{\red{}shift}: Move all Parameters Up}
  \begin{itemize}
  \item Sometimes we want to process command-line parameters in a loop
  \item The \texttt{\textbf{\red{}shift}} statement is made for this
  %\item Say that we have four parameters: \texttt{\$1} has the value
  %  \texttt{one}, \texttt{\$2} has the value \texttt{two},
  %  \texttt{\$3} has the value \texttt{three} and \texttt{\$4} has the
  %  value \texttt{four}
  \item Say that we have four parameters:
    \par\smallskip\par%
    \begin{tabular}[t]{@{}>{\ttfamily}l>{\ttfamily}ll%
        >{\ttfamily}l>{\ttfamily}l@{}}
      \toprule%
      \textnormal{\textbf{parameter}} & \textnormal{\textbf{value}} &&
      \textnormal{\textbf{parameter}} & \textnormal{\textbf{value}}\\
      \cmidrule(r{0.75em}){1-2} \cmidrule(l{0.25em}){4-5}%
      \$1 & one && \$3 & three \\
      \$2 & two && \$4 & four \\
      \bottomrule
    \end{tabular}
    \par\smallskip\par%
    
  \item Then after executing the \texttt{shift} statement, the values
    are now:
    \par\smallskip\par%
    \begin{tabular}[t]{@{}>{\ttfamily}l>{\ttfamily}ll%
        >{\ttfamily}l>{\ttfamily}l@{}}
      \toprule%
      \textnormal{\textbf{parameter}} & \textnormal{\textbf{value}} &&
      \textnormal{\textbf{parameter}} & \textnormal{\textbf{value}}\\
      \cmidrule(r{0.75em}){1-2} \cmidrule(l{0.25em}){4-5}%
      \$1 & two && \$3 & four \\
      \$2 & three && \$4 & \textnormal{\emph{no longer exists}} \\
      \bottomrule
    \end{tabular}
    %\texttt{\$1} has the value \texttt{two}, \texttt{\$2} has the
    %value \texttt{three} and \texttt{\$3} has the value \texttt{four},
    %and \texttt{\$4} no longer exists.
  \end{itemize}
\end{slide}

\begin{slide}{\texttt{shift}: Many Places}
  \begin{itemize}
  \item You can give a number argument to \texttt{shift}:
    \begin{itemize}
    \item If before, we have four parameters:
      \par\smallskip\par%
      \begin{tabular}[t]{@{}>{\ttfamily}l>{\ttfamily}ll%
          >{\ttfamily}l>{\ttfamily}l@{}}
        \toprule%
        \textnormal{\textbf{parameter}} & \textnormal{\textbf{value}} &&
        \textnormal{\textbf{parameter}} & \textnormal{\textbf{value}}\\
        \cmidrule(r{0.75em}){1-2} \cmidrule(l{0.25em}){4-5}%
        \$1 & one && \$3 & three \\
        \$2 & two && \$4 & four \\
        \bottomrule
      \end{tabular}
      \par\smallskip\par%
      %\texttt{\$1} has the
      %value \texttt{one}, \texttt{\$2} has the value \texttt{two},
      %\texttt{\$3} has the value \texttt{three} and \texttt{\$4} has
      %the value \texttt{four}
  \item After executing the statement:
\begin{alltt}
$ \textbf{shift 2}
\end{alltt}%$
    we have two parameters left:
    \par\smallskip\par%
    \begin{tabular}[t]{@{}>{\ttfamily}l>{\ttfamily}ll%
        >{\ttfamily}l>{\ttfamily}l@{}}
      \toprule%
      \textnormal{\textbf{parameter}} & \textnormal{\textbf{value}} &&
      \textnormal{\textbf{parameter}} & \textnormal{\textbf{value}}\\
      \cmidrule(r{0.75em}){1-2} \cmidrule(l{0.25em}){4-5}%
      \$1 & three && \$3 & \textnormal{\emph{no longer exists}} \\
      \$2 & four && \$4 & \textnormal{\emph{no longer exists}} \\
      \bottomrule
    \end{tabular}
    %\texttt{\$1} has the value
    %\texttt{three} and \texttt{\$2} has the value \texttt{four};
    %\texttt{\$3} and \texttt{\$4} no longer exist.
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}{Command-Line Options---1}
  \begin{itemize}
  \item Sometimes we want to modify the behaviour of a shell script
    \begin{itemize}
    \item For example, want an \emphcolour{option} to show more
      information on request
   \item could use an option ``\texttt{-v}'' (for ``verbose'') to tell
     the shell script that we want it to tell us more information about
     what it is doing
   \item If script is called \texttt{showme}, then we could use our
     \texttt{-v} option like this:
\begin{alltt}
$ \textbf{showme -v}
\end{alltt}%$
   \item the script then shows more information.
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}{Command-Line Options---2}
  \begin{itemize}
  \item For example, We might provide an option to give a starting
    point for a script to search for \SUID programs
  \item Could make the option \texttt{-d \meta{directory}}
  \item If script is called \texttt{findsuid}, could call it like
    this:
\begin{alltt}
$ \textbf{findsuid -d /usr}
\end{alltt}%$
    to tell the script to start searching in the directory
    \texttt{/usr} instead of the current directory
  \end{itemize}
\end{slide}

\begin{slide}{Command-Line Options---3}
  \begin{itemize}
  \item We could do this using \texttt{shift}, a \texttt{while} loop,
  and a \texttt{case} statement, like this:
\begin{alltt}
while [ -n "$(echo $1 | grep '-')" ]
do
    case $1 in
        -v) VERBOSE=1 ;;
        -d)
            shift
            DIRECTORY=$1
            ;;
        *)  echo "usage: $0 [-v] [-d dir]"
            exit 1 ;;
    esac
    shift
done
\end{alltt}%$
  \end{itemize}
\end{slide}

\begin{slide}[toc={\texttt{getopts}---4},bm={\texttt{getopts}---4}]%
{\texttt{\red{}getopts}: Command-Line Options---4}
  \begin{itemize}
  \item Problems with above solution: inflexibility:
    \begin{itemize}
    \item Does not allow options to be ``bundled'' together like
      \texttt{-abc} instead of \texttt{-a -b -c}
    \item Requires a space between option and its argument, i.e.,
      doesn't let you do \texttt{-d/etc} as well as \texttt{-d /etc}
%%     \item Other parameters must come last; they cannot be mixed up
%%       with the options
    \item Better method: use the built-in command
    \texttt{\textbf{\red{}getopts}}:
      {\footnotesize%
\begin{alltt}
while getopts ":vd:" opt
do
    case opt in
        v) VERBOSE=1 ;;
        d) DIRECTORY=$OPTARG ;;
        *)  echo "usage: $0 [-v] [-d dir]"
            exit 1 ;;
    esac
done
shift $((OPTIND - 1))
\end{alltt}%$
  }
    \end{itemize}
  \end{itemize}
\end{slide}

% This is what emacs' shell script mode does for insert->options:
%% while getopts ::vd: OPT; do
%% case $OPT in
%% :|+:)

%% ;;v|+v)

%% ;;d|+d)
%% "$OPTARG"
%% ;;*)
%% echo "usage: ${0##*/} [+- ARG] [+-vd ARG} [--] ARGS..."
%% exit 2
%% esac
%% done
%% shift $[ OPTIND - 1 ]
%$

\begin{slide}[toc=\texttt{getopts}---5]%
    {\texttt{getopts}: Command-Line Options---5}
  \begin{itemize}
  \item \texttt{getopts} takes two arguments:
    \begin{itemize}
    \item first comes the string that can contain letters and colons.
      \begin{itemize}
      \item Each letter represents one option
      \item A colon comes after a letter to indicate that option takes
        an arguement, like \texttt{-d \texttt{directory}}
      \item A colon at the beginning makes \texttt{getopts} less
        noisy, so you can provide your own error message, as shown in
        the example.
      \end{itemize}
    \item The second is a variable that will hold the option (without
      the hyphen ``\texttt{-}'')
    \end{itemize}
  \item Shift out all processed options using the variable
  \texttt{OPTIND}, leaving any other arguments accessible
  \item Search for \texttt{getopts} in the \texttt{bash} man page
  \end{itemize}
\end{slide}

\tsection{Temporary Files, Signals}

\begin{slide}{Temporary Files: \texttt{mktemp}}
  \label{sld:mktemp}
  \begin{itemize}
  \item Sometimes it is convenient to store temporary data in a
    temporary file
  \item The \texttt{\textbf{\red{}mktemp}} program is designed for this
  \item We use it something like this:
\begin{alltt}
TMPFILE=$(mktemp /tmp/temp.XXXXXX) || exit 1
\end{alltt}%$
  \item \texttt{mktemp} will create a new file, replacing the
    ``\texttt{XXXXXX}'' with a random string
  \item Do \texttt{man mktemp} for the complete manual.
  \end{itemize}
\end{slide}

\begin{slide}[toc={Signals that Kill}]{Signals that may Terminate your Script}
  \begin{itemize}
  \item Many key strokes will send a \emphcolour{signal} to a process
  \item Examples:
    \begin{itemize}
    \item \key{Control-C} sends a \texttt{\red{}SIGINT} signal to the
      current process running in the foreground
    \item \key{Control-\bs} sends a \texttt{\red{}SIGQUIT} signal
    \end{itemize}
  \item When you log out, all your processes are sent a
    \texttt{\red{}SIGHUP} (hangup) signal
  \item If your script is connected to another process that terminates
    unexpectedly, it will receive a \texttt{\red{}SIGPIPE} signal
  \item If anyone terminates the program with the \texttt{\red{}kill}
  program, the default signal is \texttt{\red{}SIGTERM}
\end{itemize}
\end{slide}


\begin{slide}{Signals: \texttt{trap}}
  \begin{itemize}
\item Sometimes you want your script to clean up after itself
    nicely, and remove temporary files
  \item Do this using \texttt{\red\textbf{trap}}
  \end{itemize}
\end{slide}

\begin{slide}{Signals: \texttt{trap} Example}
  \begin{itemize}
  \item Supose your script creates some temporary files, and you want
    to remove them if your script recieves any of these signals
  \item You can ``catch'' the signal, and remove the files when the
    signals are received before the program terminates
  \item Suppose the temporary files have names stored in the variables
    \texttt{TEMP1} and \texttt{TEMP2}
  \item Then you would trap these signals like this:
\begin{alltt}
trap "rm $TEMP1 $TEMP2" HUP INT QUIT PIPE TERM
\end{alltt}
    %\vspace*{-2.5ex}
  \item Conveniently, (but not very portably), \texttt{bash} provides
    a ``pretend'' signal called \texttt{EXIT}; can add this to the
    list of signals you trap, so that the temporary files will be
    removed when the program exits normally.
  \end{itemize}
\end{slide}

\tsection{Functions}

\begin{slide}{Functions}
  \begin{itemize}
  \item The shell supports functions and function calls
  \item {\mbox{}\green{}A function works like an external command},
    except that it does not start another process
  \item Syntax:
\begin{alltt}
function \meta{functname}
\{
    \meta{shell commands}
\}
\end{alltt}
    %\vspace*{-2.5ex}
    Or:
\begin{alltt}
\meta{functname} ()
\{
    \meta{shell commands}
\}
\end{alltt}
  \end{itemize}
\end{slide}

\begin{slide}{Parameters in Functions}
  \begin{itemize}
  \item Work the same as parameters to entire shell script
  \item First parameter is \texttt{\$1}, second is \texttt{\$2},\ldots,
    the tenth parameter is \texttt{\$\{10\}}, and so on.
  \item \texttt{\$\#} is the number of parameters passed to the
    function
  \item As with command line parameters, they are read-only
  \item Assign to meaningful names to make your program more
    understandable
  \end{itemize}
\end{slide}

\begin{slide}{Example, Calling a Function}
  \begin{itemize}
  \item This is a simple example program:
\begin{verbatim}
#! /bin/sh

function cube {
    echo $(($1 * $1 * $1))
}

j=$(cube 5)
echo $j     # Output is 125
\end{verbatim}
  \item Note the use of \emphcolour{command substitution to get a
      return value}
  \item The \emphcolour{function prints result to standard output}.
  \end{itemize}
\end{slide}

\tsection{Debugging}

\begin{slide}{Debugging Shell Scripts---1}
  \begin{itemize}
  \item If you run the script with:
\begin{alltt}
$ \textbf{sh -v \meta{script}}
\end{alltt}%$
    then each statement will be printed as it is executed
  \item If you run the script with:
\begin{alltt}
$ \textbf{sh -x \meta{script}}
\end{alltt}%$
    then an execution trace will show the value of all variables as
    the script executes.
  \end{itemize}
\end{slide}


\begin{slide}{Debugging Shell Scripts---2}
  \begin{itemize}
  \item Use \texttt{echo} to display the value of variables as the
    program executes
  \item You can turn the \texttt{\red{}-x} shell option on in any part of
    your script with the line:
\begin{alltt}
set -x
\end{alltt}
    and turn it \emphcolour{off} with:
\begin{alltt}
set +x
\end{alltt}
\begin{itemize}
\item No, that's not a typo: \texttt{\red{}+x} turns it \emphcolour{off},
  \texttt{\red{}-x} turns it \emphcolour{on}.
\end{itemize}
  \item The book \emph{Learning the bash Shell} includes a \texttt{bash}
    shell debugger if you get desperate
  \end{itemize}
\end{slide}

\begin{slide}{Writing Shell Scripts}
  \begin{itemize}
  \item Build your shell script \emphcolour{incrementally}:
    \begin{itemize}
    \item Open the {\red{}editor} in one window (\emph{and
        {\red{}leave} it open}), have a terminal window open in which
      to {\green{}run your program as you write it}
    \item \emphcolour{Test as you implement}: this makes shell script
      development \emphcolour{easy}
  \item Do \emphcolour{not} write a very complex script, and
    \emph{\blue{}then} begin testing it!
    \end{itemize}
  \item Use the standard software engineering practice you know:
    \begin{itemize}
    \item Use \emphcolour{meaningful} variable names, function names
    \item Make your program \emphcolour{self-documenting}
    \item Add \emphcolour{comment blocks} to explain obscure or
      difficult parts of your program
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}{Useful External Programs---1}
  Each of these has a manual page, and many have info manuals.  Read
  their online documentation for more information.
  \begin{itemize}
  \item \texttt{awk} --- powerful tool for processing columns of data
  \item \texttt{basename} --- remove directory and (optionally)
    extension from file name
  \item \texttt{cat} --- copy to standard output
  \item \texttt{cut} --- process columns of data
  \item \texttt{du} --- show disk space used by directories and files
  \item \texttt{egrep}, \texttt{grep} --- find lines containing
    patterns in files
  \item \texttt{find} --- find files using many criteria
  \end{itemize}
\end{slide}


\begin{slide}{Useful External Programs---2}
  \begin{itemize}
  \item \texttt{last} --- show the last time a user was logged in
  \item \texttt{lastb} --- show last bad log in attempt by a user
  \item \texttt{rpm} --- \RPM package manager: manage software package
    database
  \item \texttt{sed} --- stream editor: edit files automatically
  \item \texttt{sort} --- sort lines of files by many different
    criteria
  \item \texttt{tr} --- translate one set of characters to another set
  \item \texttt{uniq} --- replace repeated lines with just one line,
    optionally with a count of the number of repeated lines
  \end{itemize}
\end{slide}

\tsection{Regular Expressions}

\begin{slide}{Regular Expressions}
  \begin{itemize}
  \item Many programs and programming languages use
    \emphcolour{regular expressions}, including {\green{}Java} 1.4 and
    later, {\green{}Perl}, {\green{}VB.NET}, {\green{}C\#} (and any
    language using the .NET Framework), {\green{}PHP},
    {\green{}Python}, {\green{}Ruby}, {\green{}Tcl} and
    {\green{}MySQL} (plus many others; even {\green{}MS~Word} uses
    regular expressions under \mbox{\underline{E}dit $\to$ \underline{F}ind
    $\to$ \underline{M}ore $\to$ \underline{U}se wildcards})
  \item These programs use regular expressions:
    \begin{itemize}
    \item \texttt{\textbf{\green{}grep}}, \texttt{\textbf{\green{}egrep}},
    \texttt{\textbf{\green{}sed}}, \texttt{\textbf{\green{}awk}}
    \end{itemize}
  \item All programmer's editors support regular expressions ({\green{}Emacs},
    {\green{}vi},\,\ldots)
  \item \emph{Regular expressions} provide a \emphcolour{powerful
      language} for \emphcolour{manipulating data} and
    \emphcolour{extracting important information} from masses of data
  \end{itemize}
\end{slide}

\begin{slide}[toc={What is In a RegEx?}]{What is In a Regular Expression?}
  \begin{itemize}
  \item There are two types of character in a regular expression:
    \begin{itemize}
    \item \emphcolour{Metacharacters}
      \begin{itemize}
      \item These include:
      \item {\mbox{}\red{}\texttt{*} \texttt{\bs} \texttt{.} \texttt{+}
      \texttt{?} \texttt{\textasciicircum} \texttt{(} \texttt{)}
      \texttt{[} \texttt{\{} \texttt{\textbar}}
      \end{itemize}
    \item Ordinary, \emphcolour{literal} characters:
      \begin{itemize}
      \item i.e., all the other characters that are not metacharacters
      \end{itemize}
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}{Literal characters}
  \begin{itemize}
  \item Find all lines containing "\texttt{chan}" in the password
    file:
\begin{alltt}
$ \textbf{grep chan /etc/passwd}
\end{alltt}%$
  \item The \emphcolour{regular expression} is "\texttt{\blue{}chan}"
  \item It is made entirely of literal characters
  \item It matches only lines that contain the \emphcolour{exact}
    string
  \item It will match lines containing the words \texttt{\red{}chan},
    \texttt{{\red{}chan}ged}, \texttt{mer{\red{}chan}t},
    \texttt{me{\red{}chan}ism},\ldots
  \end{itemize}
\end{slide}

\begin{slide}{Character Classes: \texttt{[\ldots]}}
  \begin{itemize}
  \item A character class represents \emph{one} character
  \item Examples:%
    {\footnotesize%
\begin{alltt}
# Find all words in the dictionary that contain a vowel:
$ \textbf{grep "[aeiou]" /usr/share/dict/words}
# Find all lines that contain a digit:
$ \textbf{grep "[0123456789]" /usr/share/dict/words}
# Find all lines that contain a digit:
$ \textbf{grep "[0-9]" /usr/share/dict/words}
# Find all lines that contain a capital letter:
$ \textbf{grep "[A-Z]" /usr/share/dict/words}
\end{alltt}%
    }
  \end{itemize}
\end{slide}

\begin{slide}[toc=\texttt{[\textasciicircum\ldots]}]%
  {Negated Character Classes: \texttt{[\textasciicircum\ldots]}}
  \begin{itemize}
\item Examples of negated character classes:
    {\small%
\begin{alltt}
# Find all words in the dictionary
# that contain a character that is not a vowel:
$ \textbf{grep "[^aeiou]" /usr/share/dict/words}
# Two ways of finding all lines that contain
# a character that is not a digit:
$ \textbf{grep "[^0123456789]" /usr/share/dict/words}
$ \textbf{grep "[^0-9]" /usr/share/dict/words}
# Find all lines that contain a character
# that is not a digit, or a letter
$ \textbf{grep "[^0-9a-zA-Z]" /usr/share/dict/words}
\end{alltt}%
    }
  \item Remember: each set of square brackets represents exactly
  \emphcolour{one} character.
  \end{itemize}
\end{slide}

\begin{slide}{Match Any Character}
  \begin{itemize}
  \item The dot ``\texttt{.}'' matches \emphcolour{any single
      character}, except a newline.
  \item The pattern `\texttt{.....}' matches all lines that contain at
    least five characters
  \end{itemize}
\end{slide}


\begin{slide}[toc={Match Start or End}]{Matching the Beginning or End of Line}
  \begin{itemize}
  \item To match a line that contains exactly five characters:
\begin{alltt}
$ \textbf{grep '^.....$' /usr/share/dict/words}
\end{alltt}
\item The hat, {\red\verb+^+} represents the \emphcolour{position}
  right at the \emphcolour{start} of the line
\item The dollar \texttt{\red\$} represents the \emphcolour{position}
  right at the \emphcolour{end} of the line.
  \item Neither \verb+^+ nor \texttt{\$} represents a character
  \item {\mbox{}\green{}They represent a position}
  \item Sometimes called \emphcolour{anchors}, since they anchor the
    other characters to a specific part of the string
  \end{itemize}
\end{slide}

\begin{slide}[toc={Repetitions}]{Match Repetitions: \texttt{*}, \texttt{?},
    \texttt{+}, \texttt{\{n\}}, \texttt{\{n,m\}}}
  \begin{itemize}
  \item To match \emphcolour{zero} or more:
    
  \item \texttt{a*} represents zero or more of the lower case letter
    \texttt{a}, so the pattern will match \texttt{""} (the empty
    string), ``\texttt{a}'', ``\texttt{aa}'',
    ``\texttt{aaaaaaaaaaaaaaa}'', ``\texttt{qwewtrryu}'' or the
    ``nothing'' in front of any string!
  \item To match \emphcolour{one} or more:
  \item `\texttt{a+}' matches one or more ``\texttt{a}''s
  \item `\texttt{a?}' matches zero or one ``\texttt{a}''
  \item `\texttt{a\{10\}}' matches exactly 10  ``\texttt{a}''s
  \item `\texttt{a\{5,10\}}' matches between 5 and 10 (inclusive) ``\texttt{a}''s
  \end{itemize}
\end{slide}

\begin{slide}{Matching Alternatives: ``\texttt{\textbar}''}
  \begin{itemize}
  \item the vertical bar represents alternatives:
  \item The regular expresssion `\texttt{nick|albert|alex}' will match
    either the string ``\texttt{nick}'' or the string
    ``\texttt{albert}'' or the string ``\texttt{alex}''
  \item Note that the vertical bar has very low precedence:
    
  \item the pattern `\texttt{\textasciicircum{}fred\textbar{}nurk}'
    matches ``\texttt{fred}'' only if it occurs at the start of the
    line, while it will match ``\texttt{nurk}'' at any position in the
    line
  \end{itemize}
\end{slide}

\begin{slide}[toc=Examples]{Putting it All Together: Examples}
  \begin{itemize}
  \item Find all words that contain at least three `\texttt{a}'s:
\begin{alltt}
$ \textbf{egrep 'a.*a.*a' /usr/share/dict/words}
\end{alltt}%$
\begin{itemize}
\item Why is this different from
\begin{alltt}
$ \textbf{egrep 'aaa' /usr/share/dict/words}
\end{alltt}%$
\end{itemize}
\item Find all words that begin in `\texttt{a}' and finish in
  `\texttt{z}', ignoring case:
\begin{alltt}
$ \textbf{egrep -i '^a.*z$' /usr/share/dict/words}
\end{alltt}%$
\begin{itemize}
\item How is this different from:
\begin{alltt}
$ \textbf{egrep -i '^a.*z' /usr/share/dict/words}
\end{alltt}%$
\end{itemize}
  \item Find all words that contain at least two vowels:
\begin{alltt}\small
$ \textbf{grep '[aeiou].*[aeiou]' /usr/share/dict/words}
\end{alltt}%$
  \item Find all words that contain \emph{exactly} two vowels:
\begin{alltt}
$ \textbf{egrep \bs
'^[^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$' \bs
/usr/share/dict/words}
\end{alltt}%$
  \item Find all lines that are empty, or contain only spaces:
\begin{alltt}
$ \textbf{grep '^\ *$' file}
\end{alltt}%'
  \end{itemize}
\end{slide}

\tsection{\texttt{awk} and \texttt{sed}}

\begin{slide}{Basic \texttt{awk}}
  \begin{itemize}
  \item \texttt{\textbf{\red{}awk}} is a complete programming language
  \item Mostly used for one-line solutions to problems of
    \emphcolour{extracting columns of data} from text, and processing
    it
  \item A complete book is available on \texttt{awk}; you can buy it
    here: \url{http://www.oreilly.com/catalog/awkprog3/} or 
  \item read it on
    your computer, as it is the official manual for \texttt{gawk}
    (\GNU awk); do
\begin{alltt}
$ \textbf{info gawk}
\end{alltt}%$
or read it in Emacs. 
\begin{itemize}
\item A printable postscript file of the book (353 pages) is on my
  computer at \path{/usr/share/doc/gawk-3.1.3/gawk.ps}
\end{itemize}
   %\url{http://www.ssc.com/ssc/eap/}.
  \end{itemize}
\end{slide}

\begin{slide}{What Does \texttt{awk} Do?}
  \begin{itemize}
  \item \texttt{awk} reads file(s) or standard input \emphcolour{one
      line at a time}, and
  \item automatically \emph{\blue{}splits the line into fields}, and
    calls them \texttt{\$1}, \texttt{\$2},\ldots, \texttt{\$NF}
  \item \texttt{NF} is equal to the \emph{\blue{}number of fields} the
    line was split into
  \item \texttt{\$0} contains the \emph{\blue{}whole line}
  \item \texttt{awk} has an option \texttt{-F} that allows you to
    select another pattern as the \emph{\blue{}field separator}
    \begin{itemize}
    \item Normally \texttt{awk} splits \emph{\blue{}columns} by
      \emph{\blue{}white space}
    \end{itemize}
  \item To execute code after all lines are processed, create an
    \emph{\blue{}\texttt{END} block}.
  \end{itemize}
\end{slide}

\begin{slide}{\texttt{awk} Examples}
  \begin{itemize}
  \item Print the sizes of all files in current directory:
\begin{alltt}
 \textbf{ls -l | awk '\{print $5\}'}
\end{alltt}
  \item Add the sizes of all files in current directory:
\begin{alltt}
 \textbf{ls -l | awk '\{sum += $5\} END\{print sum\}'}
\end{alltt}
  \item Print only the permissions, user, group and file names of
  files in current directory:
\begin{alltt}
 \textbf{ls -l | awk '\{print $1, $3, $4, $NF\}'}
\end{alltt}
  \end{itemize}
\end{slide}


\begin{slide}{\texttt{sed}---the Stream Editor}
  \begin{itemize}
  \item \texttt{sed} provides many facilities for editing files
  \item The \emphcolour{substitute} command, \texttt{\red{}s///}, is the
    most important
  \item The syntax (using \texttt{sed} as an editor of standard input),
    is:
\begin{alltt}
$ \textbf{sed 's/\meta{original}/\meta{replacement}/'}
\end{alltt}%$
  \item Example: replace the first instance of \texttt{Windows} with
    \texttt{Linux} on each line of the input:
\begin{alltt}
 \textbf{sed 's/Windows/Linux/'}
\end{alltt}
  \item Example: replace \emph{all} instances of \texttt{Windows} with
    \texttt{Linux} on each line of the input:
\begin{alltt}
 \textbf{sed 's/Windows/Linux/g'}
\end{alltt}
\begin{itemize}
\item Note: by default, \texttt{sed} uses ``basic regular
  expressions'', which require a backslash `\bs' in front of the
  metacharacters '\{', `\texttt{(}', `\texttt{)}',
  `\texttt{\textbar}', `\texttt{+}' and `\texttt{?}'.
\item To use ``extended regular expressions'' (which we covered here),
  call \texttt{sed} with the option \texttt{-r}, as in this example:
\begin{alltt}
$ \textbf{sed -r s/a+//}
\end{alltt}%$
\end{itemize}
\end{itemize}
\end{slide}

\begin{slide}{\texttt{sed}---Backreferencees}
  \begin{itemize}
  \item You can match part of the \texttt{\meta{original}} in a
    \texttt{sed -r} substitute command, and put that part back into the
    replacement part.
  \item You enclose the part you want to refer to later in
    \texttt{(\ldots)}
  \item You can get the first value in the replacement part by
    \texttt{\bs1}, the second opening parenthesis of
    \texttt{(\ldots)} by \texttt{\bs2}, and so on.
  \end{itemize}
\end{slide}  


\begin{slide}[toc={Backrefs Example}]{\texttt{sed}---Backreferencees: Example}
  \begin{itemize}
  \item If you do
\begin{alltt}
$ \textbf{find /etc | xargs file -b}
\end{alltt}%$
you will get a lot of output like this:
\begin{alltt}
symbolic link to bg5ps.conf.zh_TW.Big5
symbolic link to rc.d/rc.local
symbolic link to rc.d/rc
symbolic link to rc.d/rc.sysinit
symbolic link to ../../X11/xdm/Xservers
\end{alltt}
  %\vspace*{-2.5ex}
\item If you want to edit each line to remove everything after
  ``\texttt{symbolic link}'', then you could pipe the data through
  \texttt{sed} like this:
\begin{alltt}
$ \textbf{find /etc | xargs file -b \bs
| sed -r 's/(symbolic link).*/\bs1/'}
\end{alltt}%$
  %\vspace*{-2.5ex}
\item See slide~\ref{sld:find-examples-1} for an application
  \end{itemize}
\end{slide}

\tsection{\texttt{find}}

\begin{slide}{\texttt{find} Examples}
  \label{sld:find-examples-1}
  \begin{itemize}
  \item Count the number of unique manual pages on the computer:
\begin{alltt}
$ \textbf{find /usr/share/man -type f | wc -l}
\end{alltt}
  \item Print a table of types of file under the \texttt{/etc}
    directory, with the most common file type down at the bottom:
\begin{alltt}
$ \textbf{find /etc | xargs file -b \bs
  | sed -r 's/(symbolic link).*/\bs1/' \bs
  | sort \bs
  | uniq -c \bs
  | sort -n}
\end{alltt}
  \end{itemize}
\end{slide}

\begin{slide}{Finding SUID Programs}
  \begin{itemize}
  \item Finding \SUID or \SGID files:
\begin{alltt}
$ \textbf{sudo find / -type f \bs
\bs( perm -2000 -o -perm -4000 \bs) \bs
> files.secure}
\end{alltt}%$
\item Let's compare with a list of \SUID and \SGID files to see if
  there are any changes, since \SUID and \SGID programs can be a
  \emphcolour{security risk}:
\begin{alltt}
$ \textbf{sudo find / -type f \bs
\bs( perm -2000 -o -perm -4000 \bs) \bs
| diff - files.secure}
\end{alltt}%$
  \end{itemize}
\end{slide}

\begin{slide}[toc={Long \texttt{find} Example}]%
  {A \texttt{find} Example with Many Options}
  \begin{itemize}
  \item Set all directories to have the access mode 771, set all
    backup files (*.BAK) to mode 600, all shell scripts (*.sh) to mode
    755, and all text files (*.txt) to mode 644:
  \end{itemize}
  {\footnotesize%
\begin{alltt}
$ \textbf{find . \bs( -type d       -a exec chmod 771 \{\} \bs; \bs) -o \bs
         \bs( -name "*.BAK" -a exec chmod 600 \{\} \bs; \bs) -o \bs
         \bs( -name "*.sh"  -a exec chmod 755 \{\} \bs; \bs) -o \bs
         \bs( -name "*.txt" -a exec chmod 644 \{\} \bs; \bs)}
\end{alltt}%$
}
\end{slide}

\begin{slide}[toc=\texttt{rpm} Queries]{\texttt{rpm} Database Query Commands}
  \begin{itemize}
  \item The \texttt{rpm} software package management system includes a
    database with very detailed information about every file of every
    software package that is installed on the computer.
  \item You can query this database using the \texttt{rpm} command.
  \item The manual page does not give the complete picture, but there
    is a book called \emph{Maximum RPM} that comes on the Red Hat
    documentation \CD
  \item This package is installed on \texttt{ictlab}
  \item \sloppypar{}You can see the appropriate section at this \URL:
    {\tiny\url{http://nicku.org/doc/maximum-rpm-1.0/html/s1-rpm-query-parts.html}}
  \end{itemize}
\end{slide}
\end{document}
