|
|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP LINKS YOU MUST CLICK ON String and Numeric Test Statements
Looping and flow control
By: Dave Taylor
Digg This!
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 TestsOne 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 TestsThe 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. LATEST LINUX STORIES
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||