| By Dave Taylor | Article Rating: |
|
| March 10, 2005 12:00 AM EST | Reads: |
9,675 |
After a bit of confusion about what column should appear in what order, I think we're in good shape now and this should be the seventh of my columns you read. If you're just joining in now, however, I encourage you to pop over to linux.intuitive.com to catch up on the previous columns.
Last month I showed you some of the more useful string and numeric test statements available with the test command and promised that, finally, we'd get into writing some sort of shell script this time. And so we shall! This time I want to talk about looping structures, but I want to do it in the context of creating a script.
I have little kids, so games like "I'm thinking of a number between 1 and 10, guess what it is" are pretty exciting to them. Amazing to me, they never seem to figure out that if you just keep changing the "guessed" value, the parent never wins the game. Soon enough I'm sure it'll dawn on them and then they'll want to play all the time. Until then, let's simulate this simple game, which we'll call "hi-low," as a shell script.
Random Numbers
The most difficult part of any game, particularly one written as a shell script, is to pick a sufficiently random number to make things interesting. There are actually some darn interesting papers written about the randomness of random number generators and many Unixes actually include two or three different random number algorithms for programmers to use. But, hey, this is a shell script, so instead of some mondo-robust solution, let's just use something simple: the current time, in seconds, divided by the necessary denominator to generate the range desired.To get the current time in seconds, the date command allows you to specify specific elements of the current time using its confusing - but powerful - "%" notation. You can learn all about it by doing man strftime (not man date. Don't ask, just trust me on this). To get just the seconds, we'll use date +%S, as shown here:
$ date +%S
04
$ date +%S
06
$
The seconds can range from 0..59, but we'd like to constrain our game to a smaller range to make it easier. This means we'll need to do some math with the seconds value, something that we can accomplish with the expr command. I'm going to use the mod function within expr, which gives you the remainder of an uneven division and is denoted with the "%" symbol. To see why this works better, here are the values of 7..11 / 10 (0,0,0,1,1) and 7..11 % 10 (7,8,9,0,1). The latter gives better and more varied results, so that's what we'll use.
Backtick Notation
When you start writing shell scripts, your tendency at first might be to keep stuffing every value into an intermediate variable, but there's a great notational convention in shell scripts that let you have the result or output of one command fed as the input of another. No, not the pipe (which links the stdout of one command to the stdin of another) but a substitution that actually occurs on the command line itself. Old time Unix folk call this the backtick notation because you use backquotes to denote the element that should be evaluated and replaced before the rest of the command is run. For example, try this:$ echo `who`
taylor console Feb 1 17:22 taylor ttyp1 Feb 1 20:51
In this example, the who command is run and the output of the command replaces it on the command line before the echo command is called. In essence, echo sees this:
$ echo taylor console Feb 1 17:22 taylor ttyp1 Feb 1 20:51
and, naturally, echoes that information.
Going back to our code, you are now probably thinking that we can generate a random number between one and 10 by utilizing the date command and doing this:
toguess="expr `date +%s` % 10"
but it won't work. Do you know why? Try it and see what happens.
You're right. The expr isn't evaluated by the shell, it's just seen as a quoted string. Rather than use backticks within backticks (which won't work properly), it's time to flip to a second subshell evaluation notation: surrounding the command with $( and ). Now we have a working variable assignment:
$ toguess="$(expr `date +%S` % 10)"
$ echo $toguess
6
$ toguess="$(expr `date +%S` % 10)"
$ echo $toguess
2
Uh oh, running out of space! Let's stop here with this nice random number generator that'll work in a shell script and next month I promise we'll pick up from here and figure out how while loops and if statements can let us write our first shell script, the hi-low game.
Published March 10, 2005 Reads 9,675
Copyright © 2005 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Dave Taylor
Dave Taylor, a contributing editor to Linux.SYS-CON.com, has been involved with the Linux and Unix community since 1980 and has written a number of best-selling Unix books. Currently, he writes, teaches, and works as a management consultant to tech startups, along with his new venture, Ask Dave Taylor!, www.askdavetaylor.com and his personal blog is www.blog.Linux.SYS-CON.com. To contact Dave, please go to /www.intuitive.com/contact.shtml.
- Kindle 2 vs Nook
- Is Cloud Computing Like Teenage Sex?
- GovIT Expo Highlights Cloud Computing
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- Cloud Computing Can Revitalize Your Career as Software Developer
- Ubuntu-based Open Source Linux Mint Tests KDE Version
- Yahoo! SVP Shelton Shugar to Discuss Innovation at Cloud Computing Expo
- Virtualization Journal "Readers' Choice Awards" Voting Is Now Open
- Einstein, Sharks and Clouds: IT Security in the Cloud
- Adobe Flex Developer Earns $100K in New York City
- Virtualization Expo Call for Papers Deadline December 15
- Amazon Web Services Database in the Cloud
- Kindle 2 vs Nook
- Cloud CEOs, CTOs & SVPs to Speak at 4th International Cloud Computing Expo
- Is Cloud Computing Like Teenage Sex?
- 1st Annual GovIT Expo: Letter from the Technical Chair
- Ulitzer News: Search vs New Media
- The Difference Between Web Hosting and Cloud Computing
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Confessions of a Ulitzer Addict
- GovIT Expo Highlights Cloud Computing
- Twitter, Linked In, Ning and Ulitzer: Easy Personal Branding Strategy
- My Thoughts on Ulitzer
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- The i-Technology Right Stuff
- Linux.SYS-CON.com Exclusive: Linus Discloses *Real* Fathers of Linux
- After Ubuntu, Windows Looks Increasingly Bad, Increasingly Archaic, Increasingly Unfriendly
- Linus' Top Ten SCO Barbs
- A Closer Look at Damn Small Linux
- Netscape Co-Founder's 12 Reasons for Growth of Open Source
- Introducing "Cooperative Linux" - Linux for Windows, No Less
- *POINT - COUNTERPOINT SPECIAL* What's Wrong with the Open Source Community?
- Where Are RIA Technologies Headed in 2008?
- Linux.SYS-CON.com Exclusive: What Would UserLinux Look Like?
- i-Technology Viewpoint: The New Paradigm of IT Buying
- Is Linux Desktop-Ready Yet...or Not?





























