December 19, 2012

A bashism a week: testing for equality

Well known, yet easy to find just about everywhere: using the "test"/"[" commands to test for equality with two equals signs (==).

Contrary to many programming languages, if you want to test for equality in a shell script you must only use the equals sign once.

Try to keep this in mind: under a shell that implements what is required by POSIX:2001, you may hit the unexpected in the following code.

if [ foo == foo ]; then
    echo expected
else
    echo unexpected
fi

4 comments:

  1. Of course debian has a few offenders as well..

    http://codesearch.debian.net/search?q=\[.*%3D%3D+filetype%3Ashell

    My regulars expressions arent that good :)
    Maybe you can come up with a better one

    Auto file this kind of bugs with gift tag would be awesome... even tho it might not be easy

    ReplyDelete
    Replies
    1. http://codesearch.debian.net/search?q=%5C%5B%5B%5E%5D%5D*%3D%3D+filetype%3Ashell

      See https://www.mirbsd.org/man7/re_format (scroll down to “BASIC REGULAR EXPRESSIONS”)

      Which leads us to even more weird things:

      if [ $# == 2 -a $my_nunlinks != $2 ]
      “-a” is not portable, though a very common extension. Fix:
      if [ $# -eq 2 ] && [ x"$my_nunlinks" != x"$2" ]

      #bashism: [ "${i:0:1}" == "/" ] || i=$(which $i)
      Commented out, how nice. Fix:
      case $i in /*) ;; *) i=$(which "$i") ;; esac

      if [[ $(id -u) == 0 ]] ; then
      It doesn’t say if this is mksh or GNU bash. mksh has $USER_ID which eliminates the need to fork’n’exec; GNU bash probably has the same. Plus, even within the Korn shell construct of [[ … ]] “==” is not always allowed (though, in all recent shells that interpret it).

      if [ "" == "$1" ]; then
      This is pretty ouch. What happened to [ -z "$1" ] or even [ "$1" ] || …? And it’s a GNU bash script, they should be using [[ anyway.

      Delete
    2. @pajarodebian: that's what we have checkbashisms for :) it does a bit more than just running regexes.

      @Thorsten: hey, it's one bashism a week, don't spoil some of the upcoming posts :)

      Delete
  2. http://codesearch.debian.net/search?q=%5C%5B%5B%5E%5D%5D*%3D%3D+filetype%3Ashell

    See https://www.mirbsd.org/man7/re_format (scroll down to “BASIC REGULAR EXPRESSIONS”)

    ReplyDelete