Difference between revisions of "Intro to Bash Scripting"

From FreekiWiki
Jump to navigation Jump to search
Line 41: Line 41:
  
 
== Code Listings ==
 
== Code Listings ==
 +
 +
Note: name each script classX-scriptY.sh  where X stands for the class (1, 2, 3, 4), and Y stands for the script we are working on in class.
 +
  
 
=== First day -- variables ===
 
=== First day -- variables ===
Line 50: Line 53:
 
#
 
#
 
# For each "script" below, open an editor, type it in, save it,  
 
# For each "script" below, open an editor, type it in, save it,  
#    change permissions, run it, debug it., naming each script classX-scriptX.sh
+
#    change permissions to 0700, run it, debug it...
  
 
###### Script 1 ###########################################
 
###### Script 1 ###########################################
 
#
 
#
# This script just assigns a string to a variable and echoes it with expansion
+
# This script just assigns a string to a variable and echoes it with expansion.  Try putting other stuff in the variables.
 
#
 
#
# run as ./class1-script1.sh
+
# save and run as ./class1-script1.sh
 
#
 
#
  
NAME='Webb'  
+
FIRSTNAME='Webb'
echo "Hello, $NAME."
+
LASTNAME='S.'
 +
echo "Hello, $FIRSTNAME $LASTNAME"
  
 
##### Script 2 ###########################################
 
##### Script 2 ###########################################
 
#
 
#
# This script takes a parameter from the command line and uses it as the name.
+
# This script takes a parameter from the command line and uses it as the name: "variable expansion"
 
#  
 
#  
 
# try from the command line:  
 
# try from the command line:  
Line 86: Line 90:
 
#  ./class1-script3.sh 1 1
 
#  ./class1-script3.sh 1 1
 
#  ./class1-script3.sh 'one' 'two'
 
#  ./class1-script3.sh 'one' 'two'
 +
#  ./class1-script3.sh 1
 +
#
 +
# What happens when we give it weird input?
  
 
LEFT=$1
 
LEFT=$1
Line 91: Line 98:
 
RES=$(( $1 + $2 ))
 
RES=$(( $1 + $2 ))
 
echo echo "$LEFT + $RIGHT = $RES."
 
echo echo "$LEFT + $RIGHT = $RES."
echo echo '$LEFT + $RIGHT = $RES.'
+
echo echo '$LEFT + $RIGHT = $RES.' # Why does this give you what it does
  
  
 
##### Script 4 ###########################################
 
##### Script 4 ###########################################
 
#
 
#
# This script does some "shell expansion"
+
# This script does some "shell expansion" using a unix command ("date" which gives a formatted string of the date; use "date --help").
 
#
 
#
 
# try from the command line:
 
# try from the command line:
Line 105: Line 112:
 
YEAR=$( date +'%Y' )
 
YEAR=$( date +'%Y' )
 
YEARS_FORWARD=$1
 
YEARS_FORWARD=$1
echo echo "$YEAR, $(($YEAR + $YEARS_FORWARD))"
+
echo "Start at year $YEAR, finish at year $(($YEAR + $YEARS_FORWARD))"
 +
 
 +
##### Script 5 ###########################################
 +
#
 +
# This script shows shell expansion with a pipe and a regular expression,
 +
#    converting all lower case characters to "X", leaving upper case alone
 +
#
 +
# try from the command line:
 +
#  ./class1-script5.sh "blah BLAH blaH"
 +
#  ./class1-script5.sh blah BLAH blaH  # What is the difference between this and the last one?
 +
#  ./class1-script5.sh
 +
 
 +
RES=$( echo $1 | sed 's/[a-z]/X/g' )
 +
echo "After stripping of lower case, \"$1\" looks like \"$RES\""  # Why do we escape the quotes?
  
 
</pre>
 
</pre>

Revision as of 18:26, 21 October 2008

Class Description

The class: a four week course on Tues evenings covering basic and intermediate scripting in the bash shell. We will examine a file with about 15 lines of code together each night, modify the code, run it, and come up with our own scripts. We will also get to know the "Advanced Bash Scripting Guide" [1] and the Gnu "Bash Reference Manual" [2] in some depth and learn to research and solve our own programming problems. User projects are encouraged -- bring your problems and we will solve them together!

I am a fifth year Ph D student from Berkeley in Demography, writing an anthropology of a small lumber town in Oregon. I have worked as a programmer in Linux for almost 10 years, and I am currently employed part time as a software project manager at Portland State.

The first class target: Oct 28, 5:00 to 6:30, 2008. I will probably have to take off a week and delay a class in the middle of the sequence.

Some helpful links to get us started:

http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-5.htm

http://tldp.org/LDP/abs/html/

http://www.gnu.org/software/bash/manual/bashref.html

Class Outline

Day One (2008-10-28): What is a "script" and what is a "variable". We will write a simple script in nano, with comments, a "shebang" line, appropriate permissions, and simple output. We work on the idea of a variable, using shell expansion to assign output to variables, interpolating variables, and exporting environment variables. We will also examine the output and input streams ("stdin", "stdout", "stderr").

Day Two (2008-11-04): "For loops" and "word splitting". We will explore the for loop in all its glory, going over lists stored in variables and lines of input from a file. This will require a discussion of how Bash automatically splits strings into words and how we can control this through quoting syntax.

Day Three (2008-11-11): Conditionals ("if/ then" statements). We will show how to write "if" and "case" statements, and work incorporate pattern matching and "file tests" into our scripts.

Day Four (2008-11-25): Scripts, functions, command line parameters. We will show how to write a script file, get input at the command line, and look at how to write functions.

Class Approach

Each class period I will have a file of code that is on the wiki. We will go over it together, showing you how to look up questions using online documentation. You will type examples from this wiki page, with modifications to make your own scripts, run them from the command line, and fix bugs.

Code Listings

Note: name each script classX-scriptY.sh where X stands for the class (1, 2, 3, 4), and Y stands for the script we are working on in class.


First day -- variables

#!/bin/sh
#
# First lesson: always put a description of script here, along with your email
#
# For each "script" below, open an editor, type it in, save it, 
#    change permissions to 0700, run it, debug it...

###### Script 1 ###########################################
#
# This script just assigns a string to a variable and echoes it with expansion.  Try putting other stuff in the variables.
#
# save and run as ./class1-script1.sh
#

FIRSTNAME='Webb' 
LASTNAME='S.'
echo "Hello, $FIRSTNAME $LASTNAME"

##### Script 2 ###########################################
#
# This script takes a parameter from the command line and uses it as the name: "variable expansion"
# 
# try from the command line: 
#   ./class1-script2.sh 
#   ./class1-script2.sh Foobar
#   ./class1-script2.sh "Foobar Smith"
#   ./class1-script2.sh Foobar Smith 

NAME=$1
echo "Hello, $NAME."
echo Hello, $NAME.
echo Hello, "$NAME".
echo Hello, \"$NAME\".


##### Script 3 ###########################################
#
# This script does some basic math
#
# try from the command line:
#   ./class1-script3.sh 1 1
#   ./class1-script3.sh 'one' 'two'
#   ./class1-script3.sh 1
# 
# What happens when we give it weird input?

LEFT=$1
RIGHT=$2
RES=$(( $1 + $2 ))
echo echo "$LEFT + $RIGHT = $RES."
echo echo '$LEFT + $RIGHT = $RES.'  # Why does this give you what it does


##### Script 4 ###########################################
#
# This script does some "shell expansion" using a unix command ("date" which gives a formatted string of the date; use "date --help").
#
# try from the command line:
#   ./class1-script4.sh
#   ./class1-script4.sh 10
#   ./class1-script4.sh "ten"

YEAR=$( date +'%Y' )
YEARS_FORWARD=$1
echo "Start at year $YEAR, finish at year $(($YEAR + $YEARS_FORWARD))"

##### Script 5 ###########################################
#
# This script shows shell expansion with a pipe and a regular expression, 
#    converting all lower case characters to "X", leaving upper case alone
#
# try from the command line:
#   ./class1-script5.sh "blah BLAH blaH"
#   ./class1-script5.sh blah BLAH blaH  # What is the difference between this and the last one?
#   ./class1-script5.sh 

RES=$( echo $1 | sed 's/[a-z]/X/g' )
echo "After stripping of lower case, \"$1\" looks like \"$RES\""  # Why do we escape the quotes?

Second day -- for-loops



Third day -- conditionals


Fourth day -- while-read and scripting


# Take each line of stdin into FOO
#  and do something with it
C=1
while read FOO ; do             
    # files and dirs  that exist in cwd
    if [[ -e $FOO ]]; then
        echo "Got existing: $FOO"
    fi

    case $FOO in
        $PATTERN) echo "got a $PATTERN: $FOO";;
        *) echo "else" > /dev/null;;
    esac
    C=$(( $C + 1 ))
done
echo "Evaluated $C files"

# Nifty thing that could read a database and send out emails
PSQL="/opt/local/lib/postgresql83/bin/psql"
CMD=" select zcta, astext(centroid(the_geom)), 'blah blah' from  zips order by zcta "
$PSQL  postgis_pdx_2008 -F ' ' -A -t -c "$CMD" | while read ZCTA POINT; do
    echo "$ZCTA: $POINT.  Yippee!"
done