======Guess a Number (Bash Script Implementation)======
To get us going on shell scripting, here are some variations of the "Guess a number" script we started writing in class.
Look through them, try them out, and make sure everything is making sense (if not, PLEASE ASK).
=====Round One: Yes or No=====
#!/bin/bash
#
# guess.sh - guess the number the computer has chosen (1 try)
#
value=`bc -q <<< "(${RANDOM} % 10) + 1"`
echo -n "Pick a value (1-10): "
read num
if [ "${num}" -eq "${value}" ]; then
echo "You guessed correctly!"
else
echo "You did not guess the number."
fi
exit 0
=====Round Two: Yes, High, or Low=====
#!/bin/bash
#
# guess.sh - guess the number the computer has chosen (1 try)
# now with an elif
#
value=`bc -q <<< "(${RANDOM} % 10) + 1"`
echo -n "Pick a value (1-10): "
read num
if [ "${num}" -eq "${value}" ]; then
echo "You guessed correctly!"
elif [ "${num}" -lt "${value}" ]; then
echo "Too low"
else
echo "Too high"
fi
exit 0
=====Round Three: 6 tries to guess (for loop)=====
#!/bin/bash
#
# guess.sh - guess the number the computer has chosen (1 try)
# now with a for loop
#
value=`bc -q <<< "(${RANDOM} % 10) + 1"`
for ((i=1; i<=6; i++)); do
echo -n "[Guess ${i}/6] Pick a value (1-10): "
read num
if [ "${num}" -eq "${value}" ]; then
echo "You guessed correctly!"
break
elif [ "${num}" -lt "${value}" ]; then
echo "Too low"
else
echo "Too high"
fi
done
if [ "${i}" -eq 7 ]; then
echo "Too bad, my pick was ${value}"
fi
exit 0
=====Round Four: user-specified tries to guess (while loop)=====
#!/bin/bash
#
# guess.sh - guess the number the computer has chosen (1 try)
# now with a while loop
#
##
## Collect required information from the user
##
echo -n "Please enter the lower range for the computer's choice: "
read lower
echo -n "Please enter the upper range for the computer's choice: "
read upper
# Make sure we have correct relationships for our range
if [ "${lower}" -ge "${upper}" ]; then
echo "Range values non-conformant"
exit 1
fi
echo -n "How many tries do you wish to have? (1-100): "
read tries
# Make sure we have a correct choice
if [ ! "${tries}" -gt 0 ] || [ ! "${tries}" -le 100 ]; then
echo "Invalid range, MUST be somewhere 1 through 100."
exit 1
fi
##
## Computer's pick
##
# Adjust upper variable with respect to lower variable for appropriate range
let highval=${upper}-lower
value=`bc -q <<< "(${RANDOM} % ${highval}) + ${lower}"`
##
## Main program
##
i=1
while [ "${i}" -le "${tries}" ]; do
echo -n "[Guess ${i}/${tries}] Pick a value (${lower}-${upper}): "
read num
if [ "${num}" -eq "${value}" ]; then
echo "You guessed correctly!"
i=0
break
elif [ "${num}" -lt "${value}" ]; then
echo "Too low"
else
echo "Too high"
fi
let i=${i}+1
done
##
## Check to see if we are out of luck/game over
##
if [ "${i}" -gt 0 ]; then
echo "Too bad, my pick was ${value}"
fi
exit 0
Rounds three and four could each have been done with a **for** loop OR a **while** loop. When a while is used, if we need to maintain a count, we need to do it ourselves, whereas with the for loop, it takes care of it as part of the loop.
The choice of loop to use is dependent upon your choosing; there really isn't a functional difference between them, although as indicated the resulting algorithm may need to be tweaked one way or the other to accommodate the desired intent of the script.
=====Round Five: Round four but using a function=====
#!/bin/bash
#
# guess.sh - guess the number the computer has chosen (1 try)
# now with functions
#
function determine {
if [ "${num}" -eq "${value}" ]; then
echo "You guessed correctly!"
i=0
break
elif [ "${num}" -lt "${value}" ]; then
echo "Too low"
else
echo "Too high"
fi
}
function init {
##
## Collect required information from the user
##
echo -n "Please enter the lower range for the computer's choice: "
read lower
echo -n "Please enter the upper range for the computer's choice: "
read upper
# Make sure we have correct relationships for our range
if [ "${lower}" -ge "${upper}" ]; then
echo "Range values non-conformant"
exit 1
fi
echo -n "How many tries do you wish to have? (1-100): "
read tries
# Make sure we have a correct choice
if [ ! "${tries}" -gt 0 ] || [ ! "${tries}" -le 100 ]; then
echo "Invalid range, MUST be somewhere 1 through 100."
exit 1
fi
}
function pick {
##
## Computer's pick
##
# Adjust upper variable with respect to lower variable for appropriate range
let highval=${upper}-lower
value=`bc -q <<< "(${RANDOM} % ${highval}) + ${lower}"`
}
##
## Main program
##
init
pick
i=1
while [ "${i}" -le "${tries}" ]; do
echo -n "[Guess ${i}/${tries}] Pick a value (${lower}-${upper}): "
read num
determine
let i=${i}+1
done
##
## Check to see if we are out of luck/game over
##
if [ "${i}" -gt 0 ]; then
echo "Too bad, my pick was ${value}"
fi
exit 0
For those familiar with function in other languages, notice how we are just blatantly using variables, regardless of location. It would appear that bash prefers **global scope** for its variables (something to keep in mind).
=====Round Six: Round five with command-line args and function parameters=====
#!/bin/bash
#
# guess.sh - guess the number the computer has chosen (1 try)
# now with command-line arguments and function parameters
#
function determine {
you="${1}"
computer="${2}"
if [ "${you}" -eq "${computer}" ]; then
echo "You guessed correctly!"
i=0
break
elif [ "${you}" -lt "${computer}" ]; then
echo "Too low"
else
echo "Too high"
fi
}
function init {
##
## Collect required information from the user
##
if [ "$#" -ge 1 ]; then
lower="${1}"
else
echo -n "Please enter the lower range for the computer's choice: "
read lower
fi
if [ "$#" -ge 2 ]; then
upper="${2}"
else
echo -n "Please enter the upper range for the computer's choice: "
read upper
fi
# Make sure we have correct relationships for our range
if [ "${lower}" -ge "${upper}" ]; then
echo "Range values non-conformant"
exit 1
fi
if [ "$#" -eq 3 ]; then
tries="${3}"
else
echo -n "How many tries do you wish to have? (1-100): "
read tries
fi
# Make sure we have a correct choice
if [ ! "${tries}" -gt 0 ] || [ ! "${tries}" -le 100 ]; then
echo "Invalid range, MUST be somewhere 1 through 100."
exit 1
fi
}
function pick {
##
## Computer's pick
##
lo="${1}"
hi="${2}"
# Adjust upper variable with respect to lower variable for appropriate range
let highval=${hi}-${lo}
value=`bc -q <<< "(${RANDOM} % ${highval}) + ${lo}"`
}
##
## Main program
##
init ${1} ${2} ${3}
pick ${lower} ${higher}
i=1
while [ "${i}" -le "${tries}" ]; do
echo -n "[Guess ${i}/${tries}] Pick a value (${lower}-${upper}): "
read num
determine ${num} ${value}
let i=${i}+1
done
##
## Check to see if we are out of luck/game over
##
if [ "${i}" -gt 0 ]; then
echo "Too bad, my pick was ${value}"
fi
exit 0
Here we make use of command-line arguments (the $1, $2, $3, ..., $n; and $# variables), to specify potential values for upper, lower, and tries from the command-line, as follows:
lab46:~$ ./guess.sh 1 10 3
[Guess 1/3] Pick a value (1-10):
Where if we had left them out:
lab46:~$ ./guess.sh
Please enter the lower range for the computer's choice:
We're also pretending some of the variables aren't global scope (function parameters are also $1, $2, $3, etc. just set to whatever values were passed to them).