[prog] bash: string comparisons in conditionals

Riccarda Cassini riccarda.cassini at gmx.de
Sat Apr 24 11:44:58 EST 2004


Dominik Schramm wrote:
> Hi Riccarda,
> 
> I think the time has come for me to jump in on one of *your* 
> threads, too. ;-)

you're always welcome to do so... :-)

> "Riccarda Cassini" <riccarda.cassini at gmx.de> writes:
> > Actually, I did try both variants... same result: no trace of 'test'
> > or '[' whatsoever (also no exec*() other than the main script...).
> > 
> > But what's that /usr/bin/[  then for?  Hm... maybe for some other
> > ancient shells?
> 
> This is from the builtins(1) man page (i.e. bash builtins):

thanks for pointing me to this, Dominik - it answered a couple of
questions in one go...
This unix stuff is ever so configurable! I love it.

With the script

  #!/bin/bash
  
  enable -n test
  enable -n [
  
  a=-r
  
  test "$a" = "" && echo '$a' is empty
  [ "$a" = "" ]  && echo '$a' is empty

I then finally got the expected lines from strace:

  execve("/usr/bin/test", ["test", "-r", "=", ""], [/* 48 vars */]) = 0

  execve("/usr/bin/[", ["[", "-r", "=", "", "]"], [/* 48 vars */]) = 0

What is interesting here (for me) is that this works, although there
obviously is no special quoting around the '-r' (the double quotes in
the args list are merely strace's output formatting, I presume).
This of course immediately brought up my question, what would happen in
case '-r' was really meant to be interpreted as a filetest operator?
So, I created a file named '=' and tried things like:

  test -r = && echo readable    # file test
  test -r = "" && echo empty    # string comparison
  test -r = -r && echo equal    # string comparison

All of them work as desired. 'test' can obviously tell apart what to do
by the number of arguments following -r. Kudos to the programmers! Well
done. But I can be mean if I need to, so I made it even more ambiguous:

  test -r = -a -n X && echo readable

et voila, it barfs out with an error message!!  while the semantically
equivalent version

  test -n X -a -r = && echo readable

works as intended.  (I know, I got what I deserve ;-)

What do I conclude?

* 'test' is rather intelligent about correctly interpreting arguments,
  but there are limits...

* I so far haven't seen a convincing reason for having to prefix 'x',
  not even with standard /bin/sh on older systems like HP-UX 10.20
  or AIX 4.3  (the only test case that fails there is [ ! "$a" ], and
  in this case you cannot use the 'x'-technique anyway).

* I've learnt a lot in this thread.

Thanks to all who replied!!

Riccarda



-- 
NEU : GMX Internet.FreeDSL
Ab sofort DSL-Tarif ohne Grundgebühr: http://www.gmx.net/dsl



More information about the Programming mailing list