Bourne Shell Selection




  1. Exit Status

    Exit status. Every process returns an exit status ( or code) a code of 0 means the process ran successfully. A non-zero indicates an error. The exit status of the last command executed is available in $?.

    $ cat bf1
    who >/dev/null
    echo :$?:
    who | grep godzilla >/dev/null
    echo :$?:
    
    $ bf1
    :0:
    :1:
    


  2. Sequential Commands.

    Commands are run using the pipe |, ;, &, && or ||.

    |
    Prior lecture material has already covered the pipe |.
    ;
    Sequential processing is achieved through the ;.
    $ cat bf2
    ls  -ld [A-Z]*; who
    (ls -ld [A-F]*;  who) >bfo
    cat bfo
    
    $ bf2
    -rw-------  1 kochis       333 Jun 11 08:44 Cancelled.mail
    drwx------  4 kochis       512 Jun 17 15:00 Mail
    drwxr-xr-x  2 kochis       512 Jun 19 08:38 News
    kochis  console Jun 27 09:42
    kochis  ttyp0   Jun 27 09:42   (unix:0.0)
    kochis  ttyp1   Jun 27 09:42   (unix:0.0)
    -rw-------  1 kochis       333 Jun 11 08:44 Cancelled.mail
    kochis  console Jun 27 09:42
    kochis  ttyp0   Jun 27 09:42   (unix:0.0)
    kochis  ttyp1   Jun 27 09:42   (unix:0.0)
    

    &
    Run each command without waiting for the preceding command to terminate. This is how we start tasks in background.
    $ cat bf3
    ls  -ld [A-Z]* & who
    
    $ bf3
    -rw-------  1 kochis       333 Jun 11 08:44 Cancelled.mail
    drwx------  4 kochis       512 Jun 17 15:00 Mail
    kochis  console Jun 27 09:42
    kochis  ttyp0   Jun 27 09:42   (unix:0.0)
    kochis  ttyp1   Jun 27 09:42   (unix:0.0)
    $ drwxr-xr-x  2 kochis       512 Jun 19 08:38 News
    
    &&
    A double ampersand (&&) causes the following command to be executed only if the preceding command returned an exit status of 0.
    $ cat bf4
    grep vacuum /usr/lib/spell/list && echo "good word"
     
    $ bf4
    vacuum
    good word
    
    
    ||
    A double pipe (||) causes the following command to be executed only if the preceding command returned an exit status of non-zero.
    $ cat bf5
    grep $1 /usr/lib/spell/list || echo "not in dictionary"
     
    $ bf5 cochise
    not in dictionary
     
    


  3. Test

    The test command is used to check conditions in the Bourne Shell. The general format is :
    test condition
    [ condition ]
    If the condition is true test return a zero (0) if the test fails it returns a nonzero.

    1. Checking equality of strings

      $ cat bf6
      echo "strings"
      one="zip"
      
      echo example 1.
      test "$one" = zip
      echo :$?:
      
      echo example 2.
      one="zip "
      [ "$one" = zip ]
      echo :$?:
      
      echo example 3.
      test $one = zip
      echo :$?:
      
      echo example 4.
      one=
      [ $one = zip ]
      echo :$?:
      $
      
      $ bf6
      strings
      example 1.
      :0:
      example 2.
      :1:
      example 3.
      :0:
      example 4.
      bf6: test: argument expected
      $
      
      To check for inequality use !=

    2. Null Strings

      Strings may be check for null with -n (not null) or -z (null)

        
      echo "strings"
      one=
      
      test -n "$one"
      echo example 1 :$?:
      
      [ -z "$one" ]
      echo example 2 :$?:
       
      $ bf7
      strings
      example 1 :1:
      example 2 :0:
      


    3. Integer tests

      The integer operators are:

        
      -eq	equal
      -ge	greater than or equal
      -le	less than or equal
      -gt	greater than
      -lt	less than
      -ne	not equal
      
      [ $count -lt 20 ]
      


    4. File tests

      The file operators of test are:

        
      -d	file is a directory
      -f	file is an ordinary file
      -r	file is readable
      -s	file has a nonzero length
      -w	file is writable
      -x	file is executable
      
      [ -d $here ]
      


    5. Logical Operators

      The logical operators are

      -a	and
      -o	or
      
      [ -d $here -a $count -lt 100 ]
      


  4. The if statement

    The if statement is:

     if command
     then
        command
         ...
     fi
    
    $ cat bf9
    
    day=`date | tr ' ' ':' | cut -d: -f3`
    
    if [ "$day" -gt 15 ]
    then
       echo "second half of month, are you broke?"
    fi
     
    $ bf9
    second half of month, are you broke?
     
    


  5. if else

    The if else statement is:

     if command
     then
        command
         ...
     else
        command
        ...
     fi
    
    $ cat bfa
    
    day=`date | tr ' ' ':' | cut -d: -f3`
    
    if [ "$day" -gt 15 ]
    then
       echo "second half of month, are you broke?"
    else
       echo "first half of month"
    fi
     
    


  6. elif

    The elif (else if construct is):

     if command
     then
        command
         ...
     elif command
        command
        ...
     else
        command
        ....
     fi
    
    $ cat bfb
    month=`date "+%m"`
    echo the month number is $month
    if [ "$month" -eq 1 ]
    then
       echo January
    elif [ "$month" -eq 2 ]
      then
         echo February
      elif [ "$month" -eq 3 ]
        then
           echo March
        elif [ "$month" -eq 4 ]
          then
             echo April
          elif [ "$month" -eq 5 ]
            then
               echo May
            elif [ "$month" -eq 6 ]
              then
                 echo June
              elif [ "$month" -eq 7 ]
                then
                   echo July
                elif [ "$month" -eq 8 ]
                  then
                    echo August
                  elif [ "$month" -eq 9 ]
                    then
                       echo September
                    elif [ "$month" -eq 10 ]
                      then
                         echo October
                      elif [ "$month" -eq 11 ]
                        then
                           echo November
                        else
                           echo December
    fi
    
    $ bfb
    the month number is 06
    June
     
    
    Note the spacing is not important to the syntax. The preceding script could be written as:
    month=`date "+%m"`
    echo the month number is $month
    if [ "$month" -eq 1 ]
    then
       echo January
    elif [ "$month" -eq 2 ]
     then
       echo February
    elif [ "$month" -eq 3 ]
     then
       echo March
    elif [ "$month" -eq 4 ]
     then
       echo April
    elif [ "$month" -eq 5 ]
     then
       echo May
    elif [ "$month" -eq 6 ]
     then
       echo June
    elif [ "$month" -eq 7 ]
     then
       echo July
    elif [ "$month" -eq 8 ]
     then
       echo August
    elif [ "$month" -eq 9 ]
     then
       echo September
    elif [ "$month" -eq 10 ]
     then
       echo October
    elif [ "$month" -eq 11 ]
     then
       echo November
    else
       echo December
    fi
    
    


  7. The exit command

    The exit command may be used to return to the shell whenever necessary. If a value is specified then that is the value associated with the command, else exit uses the exit status from the last command issued.

    $ cat bfc1
    #!/bin/sh
    if [ $1 -ge 1 -a $1 -le 12 ]
    then 
       exit 0
    else
       exit 1
    fi
    
    $ cat bfc2
    #!/bin/sh
    if bfc1 $1
    then
       echo ok
    else
      echo bad month
    fi
    
    $ bfc2 10
    ok
    
    $ bfc2 17
    bad month
    


  8. Case statement

    The case syntax is:

     case word
     in
      pattern1) commands ;;
      pattern2) commands ;;
     esac
    
    $ cat bfd
    month=$1
    case "$month"
    in
       1 ) echo January ;;
       2 ) echo February ;;
       3 ) echo March  ;;
       4 ) echo April ;;
       5 ) echo May  ;;
       6 ) echo June ;;
       7 ) echo July ;;
       8 ) echo August  ;;
       9 ) echo September ;;
       10) echo October  ;;
       11) echo November ;;
       12) echo December ;;
    esac
    
    $ bfd 4
    April
    
    $ bfd 10
    October
    

    1. Case patterns

      Case uses the same meta characters as file name expansion in specifying a pattern. * which can match anything is used as a default case.

      $ cat bfe
      month=$1
      case "$month"
      in
         [Jj]an* ) echo January ;;
         [Ff]eb* ) echo February ;;
         [Mm]ar* ) echo March  ;;
         [Aa]pr* ) echo April ;;
         [Mm]ay  ) echo May  ;;
         [Jj]un* ) echo June ;;
         [Jj]ul* ) echo July ;;
         [Aa]ug* ) echo August  ;;
         [Ss]ep* ) echo September ;;
         [Oo]ct* ) echo October  ;;
         [Nn]ov* ) echo November ;;
         [Dd]ec* ) echo December ;;
          *) echo not valid input ;;
      esac
       
      $ bfe jan
      January
      
      $ bfe Jan
      January
      
      $ bfe Augu
      August
      
      $ bfe junk
      June
      
      $ bfe fly
      not valid input
      


    2. Alternate patterns

      Alternate patterns may be selected using the | (or) in the pattern selection.

      $ cat bff
      month=$1
      case "$month"
      in
          2 ) echo 28 or 29 Days ;;
          4 | 6 | 9 | 11 ) echo 30 Days ;;
          [13578] | 1[02] ) echo 31 days ;;
         *) echo not valid input ;;
      esac
      $
      $ bff 2
      28 or 29 Days
      $ bff 6
      30 Days
      $ bff 10
      31 days
      $ bff 7
      31 days
      $ bff 13
      not valid input
      $
      


  9. The Null Statement

    The null statement : does nothing , but may be useful for certain constructs.

    $ cat bfg
    if grep $1 /usr/dict/words >/dev/null
    then
     :
    else
     echo spelling is terrible
    fi
    
    $ bfg monkey
    
    $ bfg mankey
    spelling is terrible
    

© Allan Kochis Last revision 10/16/2000