| By Dave Taylor | Article Rating: |
|
| February 8, 2005 12:00 AM EST | Reads: |
13,796 |
Last month I talked about the file-related options to the test command and how that helps you create smart and sophisticated shell scripts. This time I want to look at the additional conditions available for looping and flow control.
String Tests
One common test in shell scripts is to ascertain whether something the user has typed in or something pulled out of a data stream or file matches a specific pattern or string. The first of these tests is -z $string, which returns true if the string is zero length, false otherwise. Consider this snippet:empty="" if [ -z $empty ] ; then echo the length of empty is zero else echo the length of empty is non-zero fi
You can easily experiment and verify that if you set the variable empty to anything at all, the test will be nonzero, and if you leave it blank (or don't have it as a defined variable at all, for that matter) it'll be considered zero.
Somewhat confusingly, string tests in the test program (that is, string tests for shell scripts overall) are done with the following four operators: =, !=, <, or >. If you want to test a variable to see if it's a certain value, here's how that would look:
if [ $yourvar = "quit" ] ; then
The concept of less than or greater than is worth a bit of explanation too: it's an ASCII comparison, so "cat" is less than "dog," but, since it's ASCII, it also means that "+++" is less than "aardvark" too. Logically, this test should then work:
if [ "+++" < "aardvark" ] ; then
In fact, that'll fail with an annoying error message "-bash: aardvark: No such file or directory." This is happening because the shell is parsing and interpreting the < as a file redirection symbol before it even hands the arguments to the test command. Annoying! To sidestep this, escape the angle bracket like this:
if [ "+++" \< "aardvark" ] ; then
To be honest, though, you won't see this very often. Much more common are the = or != notations.
To get input from the user, the shell has the read command. Here's an example of using read and a string test conditional:
echo -n "Your first name: " read answer if [ $answer = "Dave" ] ; then echo Hello Dave else echo Too bad you are not Dave fi
The one problem to be aware of with string tests is that if the variable isn't defined, doesn't have any value, or has a value that includes a space, you can end up with a syntax error. On the previous snippet, for example, entering "Super Guy" as the name produces:
test.sh: line 6: [: too many arguments
Fortunately you can sidestep this problem by making sure that you quote the variable reference. Use double quotes, though, because single quotes will prevent the variable from being expanded at all. Here's the fixed line:
if [ "$answer" = "Dave" ] ; then
Numeric Tests
The other type of test you might want to use is numeric, and this will be like a quick flashback to BASIC, if you've been around that long. The tests are -lt, -le, -eq, -ne, -gt, -ge, for less than, less than or equal, equal, not equal, greater than, or greater than or equal, respectively. Want to see if an input value is less than 10? Try this:if [ "$input" -lt 10 ] ; then
What's unfortunate is that there isn't a simple built-in test for whether values match specific criteria (for example, integer only), but with some creative thought and a little subshell transformation trick, almost all tests can be easily done. To ensure that a value is an integer, here's how I'd approach the problem:
nonums="$(echo $answer | sed 's/[0-9]//g')" if [ ! -z "$nonums" ] ; then echo "Not an integer value." exit 0 fi
The basic idea is that we delete all digits in the string, then use the ! -z test (the "!" reverses the logic of the test) to see if the resultant string is zero or not. Put in the context of an actual - albeit simple - script, here's how this would look:
echo -n "Pick a number between 1 and 20: " read answer nonums="$(echo $answer | sed 's/[0-9]//g')" if [ ! -z "$nonums" ] ; then echo "Not an integer value." exit 0 fi if [ $answer -lt 10 ] ; then echo "Your answer is less than ten" else echo "Your answer is not less than ten" fi
Let's wrap up here for now, and next month we'll look at more sophisticated loop control options, and perhaps begin building a numeric guessing game as a fun and interesting example script.
Published February 8, 2005 Reads 13,796
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?


























