if
Statementsif
... then
Constructtest
test
operatorstest
Operators for Comparing Numberstest
String Operatorstest
if ... then ... else ...
Constructif ... then ... elif ...
Constructbasename
You can connect to Gradescope to take weekly graded quiz today during the last 15 minutes of the class.
Once you start the quiz you have 15 minutes to finish it.
You can only take this quiz today.
There is not makeup for the weekly quiz because Gradescope does not permit it.
I have posted homework 11 here.
It is due this Sunday at 11:59 PM
This will be the last homework assignment.
Are there any questions before I begin?
sshd
, is always running
cron
...cron
when to run itcron
will run the jobcron
job ...
$ cat -n backup_tables.sh 1 #!/bin/bash 2 # 3 # backs up all tables in the version2 database 4 5 cd $v2/sql/bak 6 rm *.bak 2> /dev/null 7 dir=$(date +%Y-%m-%d) 8 rm -rf $dir 9 mysql version2 -u root -p$1 < $v2s/scripts/backup.sql 10 mkdir $dir 11 cp *.bak $dir 12 date=$(date +%Y-%m-%d) 13 echo $date ": Table backup complete"
rm *.bak 2> /dev/null
dir=$(date +%Y-%m-%d)
rm -rf $dir
mysql
script that actually creates the backup
mysql version2 -u root -p$1 < $v2s/scripts/backup.sql
mysql
script can restore the tables from these filesmkdir $dir
cp *.bak $dir
date=$(date +%Y-%m-%d)
echo $date ": Table backup complete"
if
Statementsif
statement, a certain segment of code is executed ...if
... then
Constructif ... then
construct
if TEST_COMMAND
then
COMMAND_1
COMMAND_2
...
fi
fi
is if
spelled backwardsif
...then
and fi
are runif
statement
$ cat foo_in_dir.sh #! /bin/bash # prompts for a directory and creates foo.txt there read -p 'Directory: ' dir if cd $dir then touch foo.txt fi
test
if
statement test
...test
takes a
boolean expression
as an argument
test
is a
built-in so in
runs inside the script process
test
operatorstest
can be used to check for a number of different conditionstest
is much more complicatedtest
has five different categories of operators
test
Operators for Comparing Numberstest
uses special operatorsOperator | Result |
---|---|
-eq | True if the numbers are equal |
-ne | True if the numbers are not equal |
-ge | True if the first number is greater than, or equal to, the second |
-gt | True if the first number is greater than the second |
-le | True if the first number is less than, or equal to, the second, |
-lt | True if the first number is less than the second |
echo ?
to see the exit status
$a=1; b=2 $ test $a -gt $b; echo $? # is a greater than b? 1 $ test $a -ge $b; echo $? # is a greater than or equal to b? 1 $ test $a -lt $b; echo $? # is a less than b? 0 $ test $a -le $b; echo $? # is a less than or equal to b? 0 $ test $a -eq $b; echo $? # is a equal to b? 1 $ test $a -ne $b; echo $? # is a not equal to b? 0
test
String Operatorstest
uses different operators with strings= | True if two strings are the same |
!= | True if two strings are different |
Operator | Result |
---|---|
-n | True if the string has a length greater than 0 |
-z | True if the string has a length of 0 |
$ s1=foo; s2=bar $ test $s1 = s2; echo $? 1 $ test $s1 != s2; echo $? 0 $ test -n ""; echo $? 1 $ test -z ""; echo $? 0
$ test "foo" = "FOO"; echo $? 1 $ test "foo" != "FOO"; echo $? 0
test
operators that can be used on files and
directories
Operator | Result |
---|---|
-d | True if the argument is the name of a directory |
-e | True if the argument is the name of a file or directory |
-f | True if the argument is the name of an ordinary file (i.e. not a directory) |
-s | True if the argument is the name of a file or directory that is not empty |
-r | True if the argument is the name of a file or directory that is readable |
-w | True if the argument is the name of a file or directory that is writable |
-x | True if the argument is the name of a file or directory that is executable |
$ ls -ld dir1 # the directory I will use for testing drwxr-xr-x 4 glenn staff 128 Aug 9 11:24 dir1 $ test -d dir1; echo $? # is it a directory? 0 $ test -e dir1; echo $? # is it a file or a directory? 0 $ test -f dir1; echo $? # is it an ordinary file? 1 $ test -s dir1; echo $? # does the directory have things in it? 0 $ test -r dir1; echo $? # do I have read permission? 0 $ test -w dir1; echo $? # do I have write permission? 0 $ test -x dir1; echo $? # do I have execute permission? 0 $ ls -l foo1.txt # the file I will use for testing -rw-r--r-- 1 glenn staff 46 Aug 9 11:24 foo1.txt $ test -e foo1.txt ; echo $? # is it a file or a directory? 0 $ test -f foo1.txt ; echo $? # is it an ordinary file? 0 $ test -s foo1.txt ; echo $? # does the file have something in it? 0 $ test -r foo1.txt ; echo $? # do I have read permission? 0 $ test -w foo1.txt ; echo $? # do I have write permission? 0 $ test -x foo1.txt ; echo $? # do I have execute permission? 1
test
expressionsOperator | Condition Tested |
---|---|
-a | Logical AND, meaning both expressions must be true |
-o | Logical OR, meaning either of the two expressions must be true |
! | Logical NOT, meaning true becomes false and false becomes true |
$ test 1 -lt 5 -a 5 -lt 10; echo $? # is 1 less than 5 AND 5 less than 10 0 $ test 5 -lt 1 -a 5 -lt 10; echo $? # is 5 less than 1 AND 5 less than 10 1 $ test 5 -lt 1 -o 5 -lt 10; echo $? # is 5 less than 1 OR 5 less than 10 0 $ test 5 -lt 1; echo $? # is 5 less than one 1 $ test ! 5 -lt 1; echo $? # is 5 NOT less than 1 0
test
if cd $dir then touch foo.txt fi
if
is followed by a boolean
expression
if (BOOEAN_EXPRESSION) {
STATEMENT;
STATEMENT;
...
}
test
[ ]
is a synonym for test
if test $word1 = $word2 then echo $word1 and $word2 are the same fi
if [ $word1 = $word2 ] then echo $word1 and $word2 are the same fi
[ ]
[
and what comes after it]
$ [ 5 -ne 6] -bash: [: missing `]'
[ ]
if ... then ... else ...
Constructif
statementif ... then
statement only does something if a condition is metread -p 'Directory: ' dir if cd $dir then touch foo.txt fi
if
statement is the if ... then ... else ...
if ... then
statement ...else
clause
if TEST_COMMAND
then
COMMAND_1
COMMAND_2
....
else
COMMAND_A
COMMAND_B
...
fi
then
and else
are executedelse
and fi
are runif
statement we can rewrite the script above
read -p 'Directory: ' dir if cd $dir 2> /dev/null then touch foo.txt else echo Cannot cd into $dir fi
$ ./foo_in_dir_2.sh Directory: xxx Cannot cd into xxx
cd
$ ./foo_in_dir_2.sh
Directory: xxx
./foo_in_dir_2.sh: line 6: cd: xxx: No such file or directory
Cannot cd into xxx
if ... then ... elif ...
Constructif
statements create a branch in the flow of controlif ... then
statement creates one branchif ... then ... else
statement creates two branchesif ... then ... elif
statement elif
stands for "else if"if ... then ... elif
statement is open ended
if TEST_COMMAND_1
then
COMMAND_1
COMMAND_2
...
elif TEST_COMMAND_2
then
COMMAND_A
COMMAND_B
...
...
[else
COMMAND_N1
COMMAND_N2
...]
fi
elif
must be followed by its own commandelif
must be followed by then
if
statement allows you to nest one
if
statement ...
if
statementelse
clause that the end is optionalelse
clause, one of the branches must be runelse
clause ...if ... then ... elif
statement ...read -p 'Directory: ' dir if cd $dir 2> /dev/null then touch foo.txt else echo Cannot cd into $dir fi
if
clauses
read -p 'Directory: ' dir if [ ! -d $dir ] # if dir is not the name of a directory then echo There is no directory named $dir elif [ ! -w $dir ] # if we don't have write permission on dir then echo Cannot create a directory in $dir elif cd $dir # 2> /dev/null then touch foo.txt else echo Cannot cd into $dir fi
$ cat compare_three_words.sh #! /bin/bash # # prompts for three words then sees if any match read -p "word 1: " word1 read -p "word 2: " word2 read -p "word 2: " word3 if [ $word1 = $word2 -a $word2 = $word3 ] then echo "Match: words 1, 2 & 3" elif [ $word1 = $word2 ] then echo "Match: words 1 & 2" elif [ $word1 = $word3 ] then echo "Match: words 1 & 3" elif [ $word2 = $word3 ] then echo "Match: words 2 & 3" else echo No match fi
$ ./compare_three_words.sh word 1: foo word 2: bar word 2: bletch No match $ ./compare_three_words.sh word 1: foo word 2: foo word 2: foo Match: words 1, 2 & 3 $ ./compare_three_words.sh word 1: foo word 2: bar word 2: bar Match: words 2 & 3 $ ./compare_three_words.sh word 1: foo word 2: foo word 2: bletch Match: words 1 & 2
exit
commandexit
terminates the sub-shell in which it is runscript
sessionexit
is a built-in
$ help exit exit: exit [n] Exit the shell. Exits the shell with a status of N. If N is omitted, the exit status is that of the last command executed.
exit
...exit
1 as an argument
exit 1
if
statement using #$ cat foo_in_dir_4.sh #! /bin/bash # creates foo.txt in a directory given at the command line if [ $# -gt 0 ] then dir=$1 else exit 1 fi if cd $dir 2> /dev/null then touch foo.txt else echo Could not go to $dir fi
Usage: PROGRAM_NAME ARG1 ARG2 ...
$ cat ./foo_in_dir_5.sh #! /bin/bash # creates foo.txt in a directory given at the command line if [ $# -gt 0 ] then dir=$1 else echo Usage: $0 DIR_NAME exit 1 fi if cd $dir 2> /dev/null then touch foo.txt else echo Could not go to $dir fi
$ ./foo_in_dir_5.sh Usage: ./foo_in_dir_5.sh DIR_NAME
basename
$ foo_in_dir_5.sh Usage: /Users/glenn/bin/shell/home/foo_in_dir_5.sh DIR_NAME
basename
can help in ths situationbasename
takes a pathname as an argument$ basename /Users/glenn/bin/shell/home/foo_in_dir_5.sh foo_in_dir_5.sh
$0
with basename $0
does not work
$ ./foo_in_dir_6.sh Usage: basename ./foo_in_dir_6.sh DIR_NAME
$ cat foo_in_dir_6.sh
#! /bin/bash
# creates foo.txt in a directory given at the command line
if [ $# -gt 0 ]
then
dir=$1
else
echo Usage: $(basename $0) DIR_NAME
exit 1
fi
if cd $dir 2> /dev/null
then
touch foo.txt
else
echo Could not go to $dir
fi
$ ./foo_in_dir_6.sh
Usage: foo_in_dir_6.sh DIR_NAME
-x
option can help with debugging-x
makes Bash print a command before running it$ cat match_three.sh #! /bin/bash # # takes three stings as input and compares them if [ $# -lt 3 ] then echo Usage: $(basename $0) STRING1 STRING2 STRING3 exit 1 fi if [ $1 = $2 -a $2 = $3 ] then echo All arguments match elif [ $1 = $2 ] then echo Arguments 1 and 2 match elif [ $1 = $3 ] then echo Arguments 1 and 3 match elif [ $2 = $3 ] then echo Arguments 2 and 3 match else echo No arguments match fi $ bash -x match_three.sh foo bar foo + '[' 3 -lt 3 ']' + '[' foo = bar -a bar = foo ']' + '[' foo = bar ']' + '[' foo = foo ']' + echo Arguments 1 and 3 match Arguments 1 and 3 match
if [ $# -lt 3 ] then echo Usage: $(basename $0) STRING1 STRING2 STRING3 exit 1 fi if [ $1 = $2 -a $2 = $3 ] then echo All arguments match elif [ $1 = $2 ] then echo Arguments 1 and 2 match elif [ $1 = $3 ] then echo Arguments 1 and 3 match elif [ $2 = $3 ] then echo Arguments 2 and 3 match else echo No arguments match fi
if [ $# -lt 3 ] then echo Usage: $(basename $0) STRING1 STRING2 STRING3 exit 1 fi if [ $1 = $2 -a $2 = $3 ] then echo All arguments match elif [ $1 = $2 ] then echo Arguments 1 and 2 match elif [ $1 = $3 ] then echo Arguments 1 and 3 match elif [ $2 = $3 ] then echo Arguments 2 and 3 match else echo No arguments match fi