== A Bourne shell irritation: no wildcard matching operator Here is an irritation that gets me every so often: the Bourne shell has no wildcard match operator that you can use in _if_ checks and the like. You can do wildcard matches, but only in _case_ statements. (Bash has the (([[ =~ ]])) operator, but it uses regular expressions instead of shell wildcards. I know, I pick nits, but shell wildcards are often simpler and they match what you use in other sh contexts.) This comes up surprisingly often, at least in the sort of shell scripts that I write. It's not insurmountable but it is inconvenient and it can make my shell scripts read less clearly. Later shells, such as Plan 9's _rc_, get this right and have built in wildcard matching and non-matching operators, and I have wound up using them relatively frequently. (Yes, there is a workaround if you are doing this often enough.) Of course, like a lot of things about the Bourne shell there are historical and philosophical reasons for this. The biggest one is a programming language design issue: you really want your wildcard matching operator to have shell support so that you do not have to keep quoting the wildcards themselves. Philosophically, the only good place to put this in the Bourne shell is as part of explicit shell syntax (ie, in a _case_ statement); inventing a magic operator that didn't do shell wildcard expansion when used as if it was a command would be at least inconsistent. (Tom Duff was willing to be this magical when creating _rc_, fortunately. It may be inconsistent but it's very convenient.) The difficulty is compounded because the natural place to put such an operator is in _test_, and _test_ started out as an external program, not something built in to the shell. If not expanding wildcards in something that looks like a command is odd in the Bourne shell, doing so for some arguments to an external program is outright serious magic. PS: _expr_ is not an adequate substitute for [[various reasons ../unix/AvoidNonzeroExits]]. === Sidebar: the workaround _case_ conditions will do variable expansion and then, if the variable expands to a wildcard, do wildcard matching on the result. So the simple way around this is to define a function: > match() { > case "$1" in > $2) return 0;; > esac > return 1 > } Then you can say '((if match $var "*.c"))' and the like. If you have to you can even write vaguely crazy things like '((if match $var "*.c" && [ -f $var ];))'.