\documentclass{ictlab}

\RCS $Revision: 1.2 $

\usepackage{alltt,key,color,amstext,answer2,float}

\usepackage[nooneline,hang,bf]{caption2}
\ifx\pdftexversion\undefined \else
  \usepackage[pdfpagemode=None,pdfauthor={Nick Urbanik}]{hyperref}
\fi

\renewcommand*{\subject}{Operating Systems and Systems Integration}

\newcommand*{\labTitle}{Lab 4, 5 Shell Programming Supplement}

\definecolor{light-blue}{rgb}{0.4,0.4,1}
\newcommand*{\gl}[1]{\textcolor{light-blue}{#1}} % good link
\newcommand*{\ex}[1]{\textcolor{green}{#1}} % executable file
\newcommand*{\bl}[1]{\colorbox{red}{\textcolor{white}{\textbf{#1}}}} % bad link

\renewcommand{\floatpagefraction}{0.75} % default is .5, to increase
% density.
\renewcommand*{\bottomfraction}{0.6} % default is 0.3
\renewcommand*{\topfraction}{0.85} % default is 0.7
\renewcommand*{\textfraction}{0.1} % default is 0.2

\setlength{\extrarowheight}{1pt}
\floatstyle{ruled}
\floatname{program}{Script}
\newfloat{program}{tbh}{lop}

\begin{document}

\section{Exercise 1}
\label{sec:exercise-1}


\begin{enumerate}
\item Make a directory $\sim$\texttt{/bin} in your home directory:
  \begin{alltt}
$ \textbf{cd}
$ \textbf{mkdir bin}
  \end{alltt}
\item Copy the following files from the network directory
  \texttt{/home/nfs/ossi-part-time/scripts} to your
  $\sim$\texttt{/bin} directory:
  \begin{alltt}
$ \textbf{cp -a /home/nfs/ossi-part-time/scripts/* \(\sim\)/bin}
  \end{alltt}%$
\item   Run and understand each of demo files:
  \begin{itemize}
  \item \texttt{var1} (see script~\vref{prg:var1.sh}),
    \texttt{var2} (see script~\vref{prg:var2.sh}),
    \texttt{var3} (see script~\vref{prg:var3.sh})
  \item \texttt{if1} (see script~\vref{prg:if1.sh}), \texttt{if2} (see script~\vref{prg:if2.sh})
  \item \texttt{arith} (see script~\vref{prg:arith.sh})
  \item \texttt{loop} (see script~\vref{prg:loop.sh}),
    \texttt{loop2} (see script~\vref{prg:loop2.sh})
  \item \texttt{case} (see script~\vref{prg:case.sh})
  \item \texttt{file1} (see script~\vref{prg:file1.sh}),
    \texttt{file2} (see script~\vref{prg:file2.sh})
  \end{itemize}
\end{enumerate}




\section{Exercise 2}
\label{sec:exercise-2}

\begin{enumerate}
\item Write a script which displays ``\texttt{Good morning}'',
  ``\texttt{Good afternoon}'' or ``\texttt{Good evening}'', on the
  monitor, depending on the time of running the script.
  \begin{explanation}
    Have a look at the \texttt{date} command: do \texttt{man date}.
    You will see that there are options to output the time in any
    format; for example, \texttt{date +\%j} will print what day of the
    year today is, i.e., from 1 to 366.
    
    You will probably want to use \emph{command substitution}, i.e.,
    use \emph{backticks}, \texttt{`...`} that is the single quotes on
    the left of your keyboard.  There is an example on Joe's slide
    ``shell variable (2), slide 13 of the latest PowerPoint slides on
    shell scripting, and also in script~\vref{prg:var2.sh}, and
    script~\vref{prg:loop.sh}, where it is used with the external
    \texttt{expr} command to do arithmetic, as an alternative to the
    (easier) built in \texttt{let} command.
    
    Of course, you will also need to use an
    \texttt{if}\ldots\texttt{elif}\ldots\texttt{else}\ldots\texttt{fi}
    statement; see script~\vref{prg:if2.sh}.
  \end{explanation}
\end{enumerate}



\section{Exercise 3}
\label{sec:exercise-3}

Write a script which:
\begin{enumerate}
\item  prompts to read your  name and age:
  \begin{alltt}
Enter your name: \textbf{Joe}
Enter your age: \textbf{25}
  \end{alltt}
  \begin{explanation}
    Use the built in \texttt{read} command to read input from the
    user.  Use \texttt{echo -n} to print the prompt without a newline
    at the end.  See script~\vref{prg:if2.sh} and
    script~\vref{prg:loop.sh}.
  \end{explanation}
\item Write the read name to the first line of a file named
  \texttt{my\_info}.
  \begin{explanation}
    Use file redirection (\texttt{>}) to do this.
  \end{explanation}
\item Change your age to $\text{age}\times 3-3$ and write the value to
  the second line of \texttt{my\_info}.
  \begin{explanation}
    You can use \texttt{let} to do the arithemtic.
    Use file redirection with appending (\texttt{>>}) to do this.
  \end{explanation}
\item Content of \texttt{my\_info}:
  \begin{alltt}
my name is Joe
my modified age is 72
  \end{alltt}
\end{enumerate}

\section{Exercise 4}
\label{sec:exercise-4}

\begin{enumerate}
\item Write a script which reads a number in units of seconds and
  converts it to the units hours:minutes:seconds and prints the result
  to standard output.
\item Your script must prompt for re-input if a negative value is
  input
  \begin{alltt}
Enter number of seconds: 12345
Result:
12345 seconds is 3:25:45
  \end{alltt}
  \begin{explanation}
    This is an exercise in arithmetic evaluation.  The best bet is to
    use the built in \texttt{let} command, but you could also use the
    external \texttt{eval} command with command substitution (i.e.,
    backticks \texttt{`...`}).  You will also need a loop to prompt
    for re-input.
  \end{explanation}
\end{enumerate}

\section{Exercise 5}
\label{sec:exercise-5}

\begin{enumerate}
\item Write a script \texttt{calculate}, which accepts 4 arguments \emph{a},
  \emph{b}, \emph{c}, \emph{d} and prints the value of $a \times
  20-b\times 2+c\div d$ to standard output.
\item An example of executing the script:
  \begin{alltt}
$ \textbf{calculate 2 12 5 2}
result of "2*20 - 12*2 + 5/2" is 18
  \end{alltt}%$
  \begin{explanation}
    This is an exercise in arithmetic evaluation.  The best bet is to
    use the built in \texttt{let} command.
  \end{explanation}
\end{enumerate}

\appendix


\section{The Shell Script Examples}
\label{sec:examples}

\begin{program}
\begin{verbatim}
#! /bin/sh
# This script shows how changes to variables made by a script
# disappear after execution of the script.

echo "Before re-assignment by this script, environment variable \$HOME is $HOME"
HOME=/root
echo "After re-assignment by this script, environment variable \$HOME is $HOME"
echo "After execution of this script, echo \$HOME"
\end{verbatim}
\caption{The script \texttt{var1} shows how variable settings
disappear after a script stops running.}
\label{prg:var1.sh}
\end{program}

\begin{program}
\begin{verbatim}
#! /bin/sh
# This script shows how to use variables.
# Variable declaration and assignment:
VAR1=abc
VAR2="this is a variable"
VAR3="today is `date` and VAR1 is $VAR1"
VAR4="\$VAR1"

# display content of variables:
echo "VAR1 is ${VAR1}"
echo "VAR2 is ${VAR2}"
echo "VAR3 is ${VAR3}"
echo "VAR4 is ${VAR4}"
echo "dollar sign is \$, backquote is \`, backslash is \\"
\end{verbatim}%$
\caption{\texttt{var2} shows how variables are assigned and read.}
\label{prg:var2.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh

# This script shows the use of positional parameters
# Please run with 4 parameters, like this:
# var3 first_parameter second third fourth

echo "command name  is $0"
echo "1st parameter is $1"
echo "2nd parameter is $2"
echo "3rd parameter is $3"
echo "4th parameter is $4"
echo "total number of parameters is $#"
\end{verbatim}
\caption{\texttt{var3} shows handling of command line
  parameters.}
\label{prg:var3.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh
echo -n "input an integer (1 to 10): "
read INPUT_VAR

if [ $INPUT_VAR -le 5 ]
then
    echo "input less than or equal to 5"
else
    echo "input is greater than 5"
fi
\end{verbatim}%$
\caption{\texttt{{if1} shows a basic application of an
    \texttt{if}\ldots\texttt{else} statement.}}
\label{prg:if1.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh
echo -n "input an integer (1 to 10): "
read INPUT_VAR

if [ $INPUT_VAR -le 2 ]
then
    echo "input less than or equal to 2"
elif [ $INPUT_VAR -lt 4 ] && [ $INPUT_VAR -gt 2 ]
then
    echo "2 < input < 4"
else
    echo "input >= 4 "
fi
\end{verbatim}
\caption{\texttt{if2} shows the use of
  \texttt{if}\ldots\texttt{elif}\ldots\texttt{fi}, and also
 shows one use of the ``\texttt{\&\&}'' operator.}
\label{prg:if2.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh
# let works with + - *  /  %
#note that there are no spaces on either the left or right side
#  of +, - , *, / , %, unless you quote the expression.
# let SUM=1 + 2  (this is wrong)
let "SUM = 1 + 2" # Okay, since quoted the spaces
let SUM=1+2 # okay, no spaces, no need for quotes
let SUB=5-1
let MUL=2*5
let DIV=10/3
let REMAINDER=10%3
let 'EQUATION = 1 + 2 - 5 * 4 / 10'

echo "SUM is ${SUM}"
echo "SUB is ${SUB}"
echo "MUL is ${MUL}"
echo "DIV is ${DIV}"
echo "REMAINDER is ${REMAINDER}"
echo "EQUATION  is ${EQUATION}"
\end{verbatim}
\caption{\texttt{arith} shows how to use \texttt{let} to assign
  arithmetic experssions to variables.}
\label{prg:arith.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh
echo "input an integer less than 4"
read VAR
n=0
while [ $VAR -lt 10 ]
do
    VAR=`expr $VAR + 1`
    n=`expr $n + 1`
    echo  "loop $n: VAR is currently equal to $VAR"
done
\end{verbatim}%$
\caption{\texttt{loop} shows the use of a \texttt{while} loop, and
also shows the use of the external program \texttt{expr} as an
alternative to using \texttt{let}.  Note that \texttt{expr} is more
portable, but \texttt{let} is easier to use.}
\label{prg:loop.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh
echo "input an integer less than 4"
read VAR
n=0
while [ $VAR -lt 10 ]
do
    let "VAR = VAR + 1"
    let "n = n + 1"
    echo "loop $n: VAR is currently equal to $VAR"
done
\end{verbatim}%$
\caption{\texttt{loop2} is the same as script {prg:loop1.sh},
  but uses \texttt{let} instead of \texttt{expr}.}
\label{prg:loop2.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh
#case control flow

echo -n "input any integer: "
read VAR

case $VAR in
    "1")  echo "input is 1"  ;;
    "2")  echo "input is 2"  ;;
    "3")  echo "input is 3"  ;;
    "4")  echo "input is 4"  ;;
    "5")  echo "input is 5"  ;;
    "6")  echo "input is 6"  ;;
    "7")  echo "input is 7"  ;;
    "8")  echo "input is 8"  ;;
    "9")  echo "input is 9"  ;;
    "10") echo "input is 10" ;;

    *)    echo "input is greater than 10" ;;   #default case
esac
\end{verbatim}%$
\caption{\texttt{case} shows how to use the \texttt{case}
  statement.}
\label{prg:case.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh

# first create a file (test) for writing
# then appending to this file

# open a file (test) for writing and assign a file descriptor 3 to this file
# file descriptor is used later for identifying  this file
# if this file does not exist, it will be created:
exec  3>test

#redirect all std output of any command to this opened file (test)
echo   "message redirect from std out to file (test)"  1>&3

# close opened file:
exec  3>&-

# open a file (test) for appending and assign a file descriptor 4 to this file
# file descriptor is used later for identifying  this file
exec  4>>test

#redirect all std output of any command to this opened file (test)
echo   "appended message redirect from std out to file (test)"  1>&4

# close opened file:
exec  4>&-
\end{verbatim}
\caption{\texttt{file1} shows techniques you can use to
  write to more than one file at a time.}
\label{prg:file1.sh}
\end{program}

\begin{program}
\begin{verbatim}
#!/bin/sh

#read content of a file line by line and echo read line to monitor

# Open an existed file (test) for reading and
# assign a file descriptor 3 to this file.
# File descriptor is used later for identifying  this file
exec 3<test

LINE_NUM=1

# Redirect all stdin of any command to read from opened file (test) of descriptor 3
while read LINE 0<&3
do
    echo  "Line ${LINE_NUM} of file (test) is: ${LINE}"
    let LINE_NUM=${LINE_NUM}+1
done

# close opened file:
exec  3>&-
\end{verbatim}%$
\caption{This script, \texttt{file2}, combines the use of
  \texttt{read} with a \texttt{while} loop, and some fancy
  file redirection.}
\label{prg:file2.sh}
\end{program}

\end{document}
