\input{configpres} \title{Introduction to Shell Programming} \maketitle \begin{frame} \frametitle{Components of a Script} \begin{itemize} \item syntax: "\#!/some/interpreter" \pause \item any program can be specified as the interpreter \pause \item example: "\#!/bin/sh" \pause \item followed by shell commands (for a shell interpreter) \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Hello World as Shell Script} \begin{lstlisting} #!/bin/sh echo 'Hello, world!' \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Variables} \begin{lstlisting} #!/bin/sh # VAR1 defined for this process VAR1=abc # set export property of VAR1 for this process # (now VAR1 is defined for future children processes) export VAR1 # VAR2 defined only for /bin/sh child process # (with export property set) VAR2=def /bin/sh # clear export property of VAR1 for this process export -n VAR1 # undefine VAR1 for this process unset VAR1 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Variables} \begin{lstlisting} #!/bin/sh VAR1=abc VAR1="a b c" echo $VAR1 echo ${VAR1} echo "${VAR1}" echo '${VAR1}' VAR1=`date` VAR1=$(date) \end{lstlisting} \end{frame} \begin{frame} \frametitle{Special Variables} \begin{description} \item[\$0] argv[0] \item[\$1] argv[1] \item[\$2] argv[2] \item[\$\#] argc \item[\$@] all arguments together as a string \item[\$\$] my PID \item[\$?] return value of most recent executed command \end{description} \end{frame} \begin{frame}[fragile] \frametitle{Example Script} \begin{lstlisting} #!/bin/sh MY_VAR=17 PAR_1=$1 now=`date` echo variable is ${MYVAR}, parameter is ${PAR_1} echo date is $now echo hostname of this machine is $(hostname) echo \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Output Redirection} \begin{lstlisting} #!/bin/sh # How many lines in addr.txt contain "Jones" ? # Store the result in "jones_count" grep Jones addr.txt | wc -l > jones_count # Append a message to a log file echo "My message" >> log_file \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Conditional Branching} \begin{lstlisting} #!/bin/sh if [ condition ] then ... else ... fi # in one line... if [ condition ]; then ...; else ...; fi \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Conditional Branching} \begin{lstlisting} #!/bin/sh # number tests: -eq -ne -lt -gt -le -ge num=15 if [ $num -lt 20 ]; then ...; fi # string tests: = != < > -n -z string="Hello" if [ $string != "hello" ]; then ...; fi \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Conditional Branching} \begin{lstlisting} #!/bin/sh # file tests: # -f is a normal file # -d is a directory # -e exists # -s exists and is not empty # -r is readable # -w is writable # -x is executable # -b is a block device # -c is a character device filename="myfile" if [ -f $filename ]; then ...; fi \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Conditional Branching} \begin{lstlisting} #!/bin/sh # all tests can be negated with '!' filename="myfile" if [ ! -f $filename ]; then ...; fi # tests can be combined with a logical and '-a' and or '-o' filename="myfile" num=15 string="Hello" if [ -f $filename -o ! $num -lt 20 -a $string != "hello" ]; then ...; fi \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Conditional Branching} \begin{lstlisting} #!/bin/sh # Does addr.txt contain "Jones" ? if grep Jones addr.txt; then ... # Return value 0 means OK exit 0 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Conditional Branching} \begin{lstlisting} #!/bin/sh VAR=abcdef case $VAR in abc) echo "exactly abc" ;; abcdef) echo "exactly abcdef" ;; abc*) echo "begins with abc" ;; *) echo "match everything" ;; esac \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Conditional Branching} \begin{lstlisting} #!/bin/sh # short circuit tests: make && make install grep Jones addr.txt || echo "No Jones found!" \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Loops} \begin{lstlisting} #!/bin/sh for filename in file1 file2 file3 do cp $filename $filename.bak done for filename in * do ... done \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Loops} \begin{lstlisting} #!/bin/sh while [ condition ] do ... done while [ condition ]; do ...; done # "while conditions" are the same as "if conditions" \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Functions} \begin{lstlisting} #!/bin/sh error_log() { echo "Error: $1" >> my_log_file } ... error_log "file not found" \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Using External Scripts} \begin{lstlisting} #!/bin/sh # include an external script . /path/to/my_other_script # run an external script /path/to/my_other_script \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Accessing Files} \begin{lstlisting} #!/bin/sh ls -1 > filelist.txt while read filename do if [ -d $filename ] then echo "$filename is a directory" fi done < filelist.txt \end{lstlisting} \end{frame} \input{tailpres}