CS计算机代考程序代写 c/c++ Java CS246-F20-01-UnixShell

CS246-F20-01-UnixShell

Lecture 1.15

• Writing bash scripts
– shift, if, case

CS246

shift
• shift [N] destructively shifts (“eats”) parameters to the

left N positions
i.e., ${1}=${N+1}, ${2}=${N+2}, …,

also, ${#} is reduced by N
– If no N, 1 is assumed.
– If N is 0 or greater than ${#}, there is no shift (but it’s not an error)

$ cat shiftIt
#!/bin/bash

echo ${1}; shift 1
echo ${1}; shift 2
echo ${1}; shift 3
echo ${1}

$ ./shiftIt 1 2 3 4 5 6 7 8 9
1

2
4
7

• shift is often used in a shell script to process command line
args before doing the “real work”
– Usually no presumed ordering on command line options; these two are

both legal and mean the same:

ssh –Y –l cs246 linux.cs.uwaterloo.ca
ssh –l cs246 –Y linux.cs.uwaterloo.ca

– How would we process this? What would the logic look like?

shift if
• Two (awkward) syntaxes (prefer the first, with “;”):

if ; then

elif ; then


else


fi

if
then

elif
then


else


fi

• testCommand is evaluated; exit status of zero implies true,
otherwise false

if test “$(whoami)” = “jfdoe” ; then
echo “Hi JF!”

else
echo “Hello user, whose name I don’t know”

fi

if diff file1 file2 > /dev/null ; then # ignore diff output
echo “same files”

else
echo “different files”

fi

if [ -x /usr/bin/cat ] ; then # alternative syntax

echo “/usr/bin/cat command available”
else

echo “no executable cat in /usr/bin, look somewhere else?”

fi

Some gotchas
• As we learned earlier, if a shell variable has no value, bash

returns the empty string when you dereference it
i.e., it is not flagged as an error, as in tcsh
– This can cause scripts to break, and you may not get a very good

indication of what went wrong, exactly

• Also, when you deference a variable, surround it in quotes or
the shell may try to process incorrectly

$ v=”yes”
$ [ $v = yes ]

$ echo $?
0
$ unset v # v has no value now
$ [ $v = ‘yes’ ] # if [ = ‘yes’ ]
bash: [: =: unary operator expected

$ v=”a b c”
$ [ $v = ‘yes’ ] # if [ a b c = ‘yes’ ]
bash: [: too many arguments

$ unset v

$ [ “$v” = ‘yes’ ] # if [ “” = ‘yes’ ], legal

$ v=”a b c”

$ [ “$v” = ‘yes’ ] # if [ “a b c” = ‘yes’ ], legal

• A case statement selectively executes one of N alternatives
based on matching a string expression with a series of
patterns (globbing)

case expression in
pattern | pattern | . . . ) commands ;;

* ) commands ;; # optional match anything

esac

– When a pattern is matched, the corresponding commands are
executed up to “;;”, and control exits the case stmt
• There is no “fall through” with “;;” like in C/C++/Java

– If no pattern is matched, the case statement does nothing

case

#!/bin/bash
# options: -h, –help, -v, –verbose, -f file, –file file
usage() {

echo “${0} [-h, –help, -v, –verbose, -f file, –file file]”
exit 1 # print message and terminate script

}
verbose=no
case “${1}” in # process single option

‘-h’ | ‘–help’ ) usage ;;
‘-v’ | ‘–verbose’ ) verbose=yes ;;
‘-f’ | ‘–file’ ) # has additional argument

shift 1 # access argument
file=”${1}”
;;

* ) usage ;; # default, has to be >= one argument
esac
if [ “$verbose” = “yes” ] ; then

echo “I can never visit Philadelphia without being reminded …”
elif [ “$file” != “” ] ; then

echo ${file}
fi

End

CS246