Fun with string comparisons in BASH/Bourne Shell. Unix/Linux/Mac OS X/Cygwin


Short form:
Compare two strings, in BASH shell script. “$?” is 0 (true) if they are equivalent:
$ t3=a; o3=a; test “$t3” = “$o3” ; echo $?
0

Capture the true/false (0/non-zero) result in a variable:
$ t3=a; o3=; test “$t3” != “$o3” ; z=`echo “$?”`; echo $z
0

Remember $? is updated after every operation, so capture its value DIRECTLY after the test!

Long form::
As used as I’m getting to the generally low quality of software help/tutorial/manuals, this one is really a new low.
Here on page 133, in chapter 5 of the Fourth Edition of Unix Shell Programming by Lowell Jay Arthur & Ted Burns, in table 5.7, states:

s1 = s2 True if strings s1 and s2 are identical

BALONEY!

babbott$ tF3=a; oF3=b; test tF3 = oF3 ; echo $?
1
babbott$ tF3=a; oF3=a; test tF3 = oF3 ; echo $?
1

What this “1” means is that “tF3” and “oF3” are DIFFERENT strings. The comparison fails, and the 1 indicates “false”. “true” is 0.

But I’m getting wise to this stuff, So I put dollar signs ahead of them to mark them for substitution and double quotes around them specifying only $, \ and ` (back quote or back tick or graves have special meanings, AND allowing the reference to be processed even if the variable doesn’t exist and has never bveen assigned a value: Anyway:

babbott$ tF3=a; oF3=a; test “$tF3” = “$oF3” ; echo $?
0
babbott$ tF3=a; oF3=b; test “$tF3” = “$oF3” ; echo $?
1

NICE! FINALLY. I’ve been trying for 2 1/2 working days to figure out how to do a string variable to string variable comparison.

The really slick thing, which is their justification, is that the double quotes protect the code from uninitialized variables:

babbott$ tF3=a; oF3=; test “$tF3” = “$oF3” ; echo $?
1
babbott$ tF3=a; oF3=a; test “$tF3” = “$oF3” ; echo $?
0
babbott$ tF3=a; oF3=a; test “$tF3” != “$oF3” ; echo $?
1
babbott$ tF3=a; oF3=; test “$tF3” != “$oF3” ; echo $?
0

Gee. Well at least I know what to expect for a while.

Oh yes, if you want that pass/fail value to use for something further, here’s the only way I”ve come up with so far- I HAVE to believe this is sillier than it needs to be, and I’ll improve it when I get smarter about this stuff. But it works, its bullet-proof and I don’t have to think about it for the moment:

babbott$ tF3=a; oF3=; test “$tF3” != “$oF3” ; z=`echo “$?”`; echo $z
0
babbott$ tF3=a; oF3=a; test “$tF3” != “$oF3” ; z=`echo “$?”`; echo $z
1

And if you wonder why I just don’t use a compound statement with -a and -o switches for AND and OR logic, its because I’m comparing four pairs of strings. If all the pairs match, then do “A” else “B” Pardon me if I don’t really want to present an 8 argument test with two levels of parenthesis, 4 equals operators for the string pairs and 3 -a operators for the booleans, to future maintainers.

Bill

Advertisements

6 responses to “Fun with string comparisons in BASH/Bourne Shell. Unix/Linux/Mac OS X/Cygwin

  1. Pardon me if I don’t really want to present an 8 argument test with two levels of parenthesis, 4 equals operators for the string pairs and 3 -a operators for the booleans, to future maintainers.

    Well, sure, but all those Teco programmers at GenRad would be so proud!

  2. Well, yeah. Or I could be really, er, efficient, and do the four pairs of string comparisons, then ttaking the compare results and ADDING THEM. If the result is anything other than 0 (zero) then the one or more comparison failed…

    Everyone knows that adding is the same as ORing… except that Unix exit codes are low true- 0 (zer0) is good, true or pass, non-zero is some kind of error. So ORing the inverted inputs is the same as NANDing them as true inputs.

    As my pal Bill Dopson used to say, if you push the “inverting” bubble through a logic gate from inputs to output or vice versa, it flips AND to NOR, OR to NAND, NOR to AND, or NAND to OR.

    Just a nice memonic that the truth table for a two input OR gate with INVERTED inputs is the same as for a two input NAND with TRUE inputs. Compare A,B NAND with A* B* OR::
    A B NAND A* B* OR
    1 1 0 0 0 0
    1 0 1 0 1 1
    0 1 1 1 0 1
    0 0 0 1 1 1

  3. As general recommendations: Always use quotes and dollar, even when they are not legally necessary. Apart from mistakes as your original, it can prevent errors through inconsistent rules and special cases (including variable values, e.g. file names, with spaces in them).

    As for your overall problem, I cannot make a definite recommendation for lack of detail; however, you may want to look into the || and && operators which often allow to chain the tests in a more readable manner than -a/-o. Consider something like [ “$a” = “$b”] && [ “$c” = “$d”] && ….

    • Thank you very much! The squrare brackets and && do look fairly clear. I have not used && and ||, taking small steps, trying not to be overwhelmed. You are right about double quotes and dollar signs. To be clear, I’m not yet ‘flowing’ and confident in my work with BASH. I may have to write a sampler that tries all the commands and some set of combinations. I also find that organizing my thoughts to describe a problem in writing sometimes makes my mistake(s) clear to me! I only post the ones I find a good solution to, or that I still haven’t solved.

  4. Bill, I want to comment on your B-25 model building project. Rarely have I found a builder so into matching the model to reality. Great information. Question, have you tried using Testor’s decal maker? I used it to scale down and make decals of my Dad’s WWII nose art from his B-25, “Panchito”. I also used a silver-gray paint to depict rain/oil strak on the leading edge of the wings.
    Keep up the good work!

    • Hi Carl,
      Thank you very much for the praise. Its hardly fair to the vast number of model builders who are better than me- the Silicon Valley Scale Modeller’s club I belong to has many members who’s work is just breathtaking. I saw the IPMS/USA Nationals one year and it was like the club but 10-100 times bigger. Some crazy good stuff.

      Bill

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s