UC Irvine, Information and Computer Science Department Winter 2000

ICS 54: Shell Programming II: Brief notes for Chapter 16


Conditional Execution

if  testcommand
  then  command(s)
fi

if  testcommand; then
  command(s)
fi


if  testcommand; then
  command(s)
else
  command(s)
fi


if  testcommand; then
  command(s)
elif  testcommand; then
  command(s)
else
  command(s)
fi

Example(s):

#!/bin/sh
# Demonstrate if
echo "\n--If 1"
if test $# -eq 0 ; then echo "I need an argument" ; exit 2 ; fi

echo "\n--If 2"
if test $# -ge 2
  then 
    echo "More than 1 argument is good"
    echo "Here they are"
    echo $*
else
  echo "Only 1 argument"
  if test -z $1 ; then echo "But it's empty" ;  ## 2nd ; not needed
  else echo "And it is $1" ; fi  ## This ; needed
fi

echo "\n--If 3"
if [ $# -lt 3 ]
  then 
    echo "Less than 3 arguments\nI'll show them"
    echo $*
elif [ $3 = "quit" ]; then echo "The third argument says \"quit\""
else
  echo "Argument 3 is $3"
fi

echo "\n--If 4"
if [  -f $1 -o -d $1 ]; then 
  echo "$1 is a regular file or directory\c"
  if [ -x $1 ]; then echo " and it is executable"; fi
else echo "Argument 1 is just another name"
fi


test

test expression    is the same as    [ expression ]
 
Be sure to include spaces around  expression  separating it from the brackets!

Tests: 0=True
Integer tests
n1 -ne n2True if integers are not equal.
n1 -eq n2True if integers n1=n2
n1 -lt n2True if integers n1<n2
n1 -le n2True if integers n1<=n2
n1 -ge n2True if integers n1>=n2
n1 -gt n2True if integers n1>n2
String tests
-z string  True if string has length zero
-n stringTrue if string has non-zero length
s1 = s2True if the 2 strings are equal
s1 != s2True if the 2 strings are not equal
stringTrue if string is not the empty string
File and Directory tests
-r fileTrue if file exists and is readable
-w fileTrue if file exists and is writable
-x fileTrue if file exists and is executable
-f fileTrue if file exists and is a regular file
-d fileTrue if file exists and is a directory
-s fileTrue if file exists and has non-zero size   
Boolean combinations of tests
! t1 True if t1 is not true
t1 -a t2True if both t1 and t2 are true
t1 -o t2True if t1 or t2 is true


Selection

case  string in
  pattern-list )
        command(s)
        ;;
  pattern-list )
        command(s)
        ;;
     * )              # fall through
         command(s)
         ;;
esac

Example:

#!/bin/sh
# Demonstrate case
set $* NoArgument
case $1 in
  [aAeEiIoOuU] )
        echo "That's a vowel."
        ;;
  *.html | *.htm )
        echo "$1 is an HTML file"
        ;;
  NoArgument )
        echo "Did you forget to provided an argument?"
        echo "How peaceful it is that way."
        ;;
     * )
       echo "I've no idea what $1 is."
       ;;
esac


Iteration

for  var in list
do
    command(s)
done


while
    command(s)2go
do
    command(s)
done


until
    command(s)2stop
do
    command(s)
done


Examples:

#!/bin/sh
# Demonstrate for
if [ ! -d "$1" ]; then echo "I need a directory" ; exit 1; fi
echo "In directory $1"
for f in `ls $1/*.html`
do
  echo "$f is an html file"
done

##### Sample Run:
  % ./for.1
  I need a directory
  % ./for.1 doc/ch1
  In directory doc/ch1
  doc/ch1/1.html is an html file
  doc/ch1/exercises.html is an html file
  doc/ch1/intro.html is an html file

########################################################

#!/bin/sh
# Demonstrate while
while read x
do
  set $x
  echo "$#: $x"
done

##### Sample Run:
  % ./while.1 < while.1
  1: #!/bin/sh
  3: # Demonstrate while
  3: while read x
  1: do
  2: set $x
  3: echo "$#: $x"
  1: done

########################################################

#!/bin/sh
# Demonstrate until
until [ $# -eq 0 ]
do
  echo "$#: $1 | \c"
  shift
  echo "$*"
done

##### Sample Run:
  % ./until.1 this will go away
  4: this | will go away
  3: will | go away
  2: go | away
  1: away | 


Conditional Conveniences, Iteration Aids and Escapes

true
Always tests/returns a true, zero, successful completion, value/exit status.
false
Always tests/returns a false, non-zero, failure completion, value/exit status.
break [n]
Exit immediately from the nth innermost enclosing loop. Normally, n is omitted and it it the most immediate enclosing loop which is exited.
continue [n]
Immediately go to the next iteration (if any) of the nth innermost enclosing loop. Normally, n is omitted and it it the most immediate enclosing loop whose current iteration is considered completed.
exit [n]
Immediately terminate the current shell script, setting/returning an exit error/status code of n (a non-negative integer). A value of zero indicates successful completion of the script. If n is omitted, 0 is assumed.
cmd1   &&   cmd2
Execute cmd1. If (and only if) it returns a true/zero/"success" exit status, then execute cmd1 and return its exit status as that of the combination of the commands.
cmd1   ||   cmd2
Execute cmd1. If (and only if) it returns a false/non-zero/"error" exit status, then execute cmd1 and return its exit status as that of the combination of the commands.

Examples:

#!/bin/sh
# while.2 -- Demonstrate while and &&
## If the first argument is a file, process it
[ -f "$1" ] && while read x y
do
   echo "$y $x"
done < $1

##### Sample Runs:
  % cat T
  This is a simple
  file on which we can
  experiment.
  % ./while.2
  % ./while.2 .
  % ./while.2 T
  is a simple This
  on which we can file
   experiment.
  %

########################################################

% cat until.2
#!/bin/sh
# until.2 -- Demonstrate until and ||
until [ $# -eq 0 ] || [ $1 = "quit" ]
do
  echo "$#: $1 | \c"
  shift
  echo "$*"
done


##### Sample Runs:
  % ./until.2 what is going on
  4: what | is going on
  3: is | going on
  2: going | on
  1: on | 
  % ./until.2 what is "going on"
  3: what | is going on
  2: is | going on
  1: going on | 
  % ./until.2 will we quit early
  4: will | we quit early
  3: we | quit early
  % 


Arithmetic Operations

sh's (modest) arithmetic capabilities are expressed using expr.

Examples:

$ echo $i

$ i=1+1
$ echo $i
1+1
$ i=`expr 1+1`
$ echo $i
1+1
$ i=`expr 1 + 1`
$ echo $i
2
$ i=`expr 7 * 6`
expr: syntax error
$ i=`expr 7 \* 6`
$ echo $i
42
$ ################
$ j=`expr i - 40`
expr: non-numeric argument
$ j=`expr $i - 40`
$ echo $j
2
$ ################
$ i=`expr \( 3 + 4 \) \* \( 12 / 2 \)`
$ echo $i
42
$ k=`expr \( 3 + 4 \) \* \( 1$j / $j \)`
$ echo $k
42
$


Comments are welcome.
Current as of 8 February 2000
HTML 4.01 Checked.