| By Dave Taylor | Article Rating: |
|
| February 8, 2005 12:00 AM EST | Reads: |
17,349 |
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 17,349
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.
- Ubuntu-based Open Source Linux Mint Tests KDE Version
- Linux Virtualization and Tired Open Source Myths
- IGEL Supports Red Hat Enterprise Virtualization 3.0
- CloudLinux Announces Support for Atomia
- Amazon Kindle Fire Gets Its Own 'Personal Cloud Desktop' with AlwaysOnPC App Launch
- SPIRIT DSP Receives 2011 INTERNET TELEPHONY Product of the Year Award
- Hadoop Quickstart: Use Whirr to automate standup of your distributed cluster on Rackspace
- Jury Gets Novell Antitrust Case Against Microsoft
- The Utility Infrastructure Security Market 2012-2022: Cybersecurity & Smart Grids
- FORTUNE Magazine Names Rackspace Among “100 Best Companies to Work For”
- EnterpriseDB Announces Availability of Postgres Plus Cloud Database
- iFollowOffice Turns to Virtual Bridges and Savvis for On-Demand Virtual Desktop Services
- i-Technology in 2012: Five Industry Predictions
- Ubuntu-based Open Source Linux Mint Tests KDE Version
- Amazon to Rent Out Supercomputers
- Amazon Émigré Starts Network Monitoring Firm
- HP’s Putting a Back Door in the Itanium Alamo
- Linux Virtualization and Tired Open Source Myths
- CloudLinux Announces Preferred Partner Program
- MapR Pushes the Hadoop Envelope
- Rightware Announces Gaming Performance Benchmark for OpenGL ES 3.0/Halti
- IGEL Supports Red Hat Enterprise Virtualization 3.0
- CloudLinux Announces Support for Atomia
- 3Dconnexion Announces its Newest 3D Mouse - the SpaceMouse Pro
- 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
- A Closer Look at Damn Small Linux
- Linus' Top Ten SCO Barbs
- SCO CEO Posts Open Letter to the Open Source Community
- Netscape Co-Founder's 12 Reasons for Growth of Open Source
- Where Are RIA Technologies Headed in 2008?
- *POINT - COUNTERPOINT SPECIAL* What's Wrong with the Open Source Community?
- Introducing "Cooperative Linux" - Linux for Windows, No Less
- Linux.SYS-CON.com Exclusive: What Would UserLinux Look Like?
- Why Recovering a Deleted Ext3 File Is Difficult . . .


















