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
    echo unexpected


  1. Of course debian has a few offenders as well..\[.*%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


      See (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.

    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 :)


    See (scroll down to “BASIC REGULAR EXPRESSIONS”)