Storm Ok, so, last time we covered a lot of material. We did variables, the read statement, if/else, and while loops. That was a lot for one class, so we are going to spend a little more time on it tonight.
Storm Did anyone complete any of the questions from last time? Anyone get the count to 20 by 2s or backwards to 0 by 2s working?
Storm Did anyone get the trickiest one working, with 2 arguments to count up or down from the entered number?
Storm or even 3 arguments?
Storm Ok, I will show how this works.
Jeff I'm still getting the near unexpected token "else"
Storm the 2 argument one is pretty easy when you fit all the pieces we learned together.
Storm jeff: You may have a missing quote or something.
Storm Let's talk about the parts that would go into the 2 arg version.
Storm to call it, we could do somethinglike
./counter.sh 3 0
Storm and we should get
3 2 1 0
Storm or if we did it:
./counter.sh 0 3
Storm we should get
0 1 2 3
Storm Thing is, how do we know which way to count? Anyone have any suggestions?
Storm Remember what the if statement does. It evaluates a statement and takes an action based on the truthfulness of that statement. If we are counting backwards then the first argument would be higher than the second. It's a perfect example of where the if statement is very handy.
if [ "$1" -gt "$2" ] ; then
Storm So, if we are in this part we are going to have to count down to the second argument, $2.
Storm And, this is something I should have introduced a while back but it kept slipping my mind.
Storm Any line that starts with a # is a comment and is not executed.
Storm Yes, the first line #!/bin/bash is a comment, it's just one with special powers.
Storm so, inside this part of the if statement we could do:
Storm then, we make our while loop to count down to $2
while [ "$1" -ge "$@" ] ; do put the count down code here done
Storm then, we need to handle the other option, to count up.
Storm We don't need another if, because we already know that $1 is less than $2 if we don't execute this part of the if statement. So, we put an else here.
Storm Now, we could put another comment.
#counting up. while [ "$1" -le "$2" ] ; do put our code to count up here, almost identical to the other loop. done
Storm now, we end our if statement with:
Storm and the only thing left to do is…
Storm so, I am going to paste this code in for you all to review. You can put it in a file and execute it if you want. If you have any questions please ask them. Some of this is pretty complex and it's all pretty important.
#!/bin/bash #set variables num1=$1 num2=$2 #find out which way to count: if [ "$num1" -gt "$num2" ] ; then while [ "$num1" -ge "$num2" ] ; do echo "$num1" num1=$(($num1 - 1)) done else while [ "$num1" -le "$num2" ] ; do echo "$num1" num1=$(($num1 + 1)) done fi exit 0
Storm Our next project is going to be a guessing game. One of those where the computer thinks of a number and you try to guess it.
Storm In bash, you can get a sudo random number from the environmental variable $RANDOM. Notice that $RANDOM is in all caps. The problem with sudo random numbers is they can be figured out, in some cases pretty easily. So, we need a way to seed the random variable. There's a lot of info on /dev/random. You can read all about it on the net and in its man page. It's all really pretty confusing. So, I found a formula that uses /dev/random to create a random number and it works well, so I use it in anything where I need a random number. Some things you end up using over and over, and if it's something like that, you should make a note of it in a file somewhere or memorize it. This is one of those things, if you use randomness in any of your scripts, this would be handy to right down for future use.
RANDOM=$(od -An -N2 -i /dev/random)
Storm Of course, if anyone knows a better way I would love to have it. This makes sure the value in $RANDOM is a random value. It gets the randomness from things like keyboard and mouse input. It generates a number based on that.
Storm With this generator, and the following formula, you should be able to create a guessing game.
variable=$(($RANDOM % highestNumber))
Storm which will store your random number between 0 and your highest number. Or if you want it to be between a specific number like 1 and 10 for example:
variable=$(($RANDOM % 10 + 1))
Storm so, for our guessing game. we first seed the random number, then we could do the 1 to 10 formula above and read the answer
read -p "Please enter your guess. " guess
Storm and of course read -p will prompt and store the answer in the variable guess. Then, we have to test to make sure the number equals the computer generated number.
if [ "$guess" -eq "$computerNumber" ] ; then echo "Right on! What are you, some sort of psychic?" else echo "hahaha, you suck, you couldn't guess your way out of a wet paper bag!" fi then exit 0
Storm Pretty easy huh? When dealing with command line arguments it may be useful to know how many were passed in to the program. This info is stored in $#
Storm With this info, you can make sure your programs have the required amount of information
if [ "$#" -ne "3" ] ; then echo "You must have exactly 3 arguments for this script" fi
if [ "$#" -gt "2" ] ; then echo " you may have up to 2 arguments for this script" fi
Storm What I would like to do, is give everyone time to work on the numbers script. It needs to know if it has 2 arguments and exit with a status of 1 and an error message if it does not.
echo "I need 2 numbers" exit 1
Storm Make a guessing game that will generate numbers between 1 and 10. It will loop until the player gets the number right. It will also give hints, You guessed too low. or, you guessed too high
Storm when the player gets the number right it should ask to play again. The letter y will cause the game to play again. Anything else exits.
Storm Here's a quick example
Storm in terminal type:
echo "$((0 / 0))"
Storm you'll get a division by 0 error
Storm the last code for any action is stored in $?
Storm so, type
Storm and it will print a 1
Storm if, however, you do
echo "$((1 + 1 ))"
Storm $? will hold a 0 which means it worked.
Storm Questions? find me on #Vinux on irc.vinuxproject.org