A Study in Bash Shell : Shell Logic and Arithmetic
Doing Arithmetic in Your Shell Script
Use $(( )) or let for integer arithmetic expressions.
COUNT=$((COUNT + 5 + MAX * 2))
let COUNT+=5+MAX*2
Branching on Conditions
if (( $# < 3 ))
then
printf "%b" "Error. Not enough arguments.\n"
printf "%b" "usage: myscript file1 op file2\n"
exit 1
elif (( $# > 3 ))
then
printf "%b" "Error. Too many arguments.\n"
printf "%b" "usage: myscript file1 op file2\n"
exit 2
else
printf "%b" "Argument count correct. Proceeding...\n"
fi
Testing for File Characteristics
#!/usr/bin/env bash
# cookbook filename: checkfile
#
DIRPLACE=/tmp
INFILE=/home/yucca/amazing.data
OUTFILE=/home/yucca/more.results
if [ -d "$DIRPLACE" ]
then
cd $DIRPLACE
if [ -e "$INFILE" ]
then
if [ -w "$OUTFILE" ]
then
doscience < "$INFILE" >> "$OUTFILE"
else
echo "can not write to $OUTFILE"
fi
else
echo "can not read from $INFILE"
fi
else
echo "can not cd into $DIRPLACE"
fi
Option | Description |
---|---|
-b | File is block special device (for files like /dev/hda1) |
-c | File is character special (for files like /dev/tty) |
-d | File is a directory |
-e | File exists |
-f | File is a regular file |
-g | File has its set-group-ID bit set |
-h | File is a symbolic link (same as -L) |
-G | File is owned by the effective group ID |
-k | File has its sticky bit set |
-L | File is a symbolic link (same as -h) |
-O | File is owned by the effective user ID |
-p | File is a named pipe |
-r | File is readable |
-s | File has a size greater than zero |
-S | File is a socket |
-u | File has its set-user-ID bit set |
-w | File is writable |
-x | File is executable |
Testing for More Than One Thing
if [ -r $FILE -a -w $FILE ]
Testing for String Characteristics
#!/usr/bin/env bash
# cookbook filename: checkstr
#
# if statement
# test a string to see if it has any length
#
# use the command line argument
VAR="$1"
#
if [ "$VAR" ]
then
echo has text
else
echo zero length
fi
#
if [ -z "$VAR" ]
then
echo zero length
else
echo has text
fi
Testing for Equal
#!/usr/bin/env bash
# cookbook filename: strvsnum
#
# the old string vs. numeric comparison dilemma
#
VAR1=" 05 "
VAR2="5"
printf "%s" "do they -eq as equal? "
if [ "$VAR1" -eq "$VAR2" ]
then
echo YES
else
echo NO
fi
printf "%s" "do they = as equal? "
if [ "$VAR1" = "$VAR2" ]
then
echo YES
else
echo NO
fi
Numeric | String | Meaning |
---|---|---|
-lt | < | Less than |
-le | <= | Less than or equal to |
-gt | > | Greater than |
-ge | >= | Greater than or equal to |
-eq | =,== | Equal to |
-ne | != | Not equal to |
Looping for a While
Use the while looping construct for arithmetic conditions:
while (( COUNT < MAX ))
do
some stuff
let COUNT++
done
for filesystem-related conditions:
while [ -z "$LOCKFILE" ]
do
some things
done
or for reading input:
while read lineoftext
do
process $lineoftext
done
Looping with a Count
$ for (( i=0 ; i < 10 ; i++ )) ; do echo $i ; done
Looping with Floating-Point Values
for fp in $(seq 1.0 .01 1.1)
do
echo $fp
done
Branching Many Ways
case $FN in
*.gif) gif2png $FN
;;
*.png) pngOK $FN
;;
*.jpg) jpg2gif $FN
;;
*.tif | *.TIFF) tif2jpg $FN
;;
*) printf "File not supported: %s" $FN
;;
esac
Parsing Command-Line Arguments
LEN=72
CHAR='-'
while (( $# > 0 ))
do
case $1 in
[0-9]*) LEN=$1
printf $LEN
;;
-c) shift;
CHAR=${1:--}
printf $CHAR
;;
*) printf 'usage: %s [-c X] [#]\n' $(basename $0) >&2
exit 2
;;
esac
shift
done
Creating Simple Menus
FILELIST=$(ls)
#Set it to a new value and you’ll get a new prompt.
PS3="0 inits >"
select file in $FILELIST
do
echo selected file:$file
done