Matching words against a list in the Bourne Shell

November 12, 2007

One of the interesting challenges in writing shell scripts is figuring out how to do as much as is practical with shell builtins and primitives. Since Bourne shell builtins are such a limited and constrained environment, the results can be somewhat perverse and peculiar and thus neat and amusing.

(If you can find an efficient way of doing things, using builtins is much faster than having to resort to external programs, especially when the system is loaded.)

My challenge today was checking whether a word was in a list of words (words don't have spaces), in a Bourne shell dialect that would work as far back as Solaris 2.5. What I came up with is:

case "$wlist" in
    $w|"$w "*|*" $w "*|*" $w") echo yes;;
    *) echo no;;
esac

(Where $w is the word and $wlist is the space-separated list of words to match against. You need the first match condition to deal with the case where $wlist consists only of $w.)

I sometimes feel I have an advantage in this sort of perversity, because I started out writing shell scripts in a version of the Bourne shell that was so old that it didn't even have test (aka [ ... ]) as a builtin. When you don't have a built in test you get a lot of experience with abusing case, because it is basically the only builtin testing operation you have.

(To this day I have a tendency to use case for condition tests where I really should use if. Something in the back of my mind is still not really convinced that things like 'if [ "$#" -eq 0 ]' don't require an external program.)

Written on 12 November 2007.
« Why vfork() got created (part 1)
Why vfork() got created (part 2) »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Nov 12 23:26:09 2007
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.