4

What is the difference:

if IsServerStarted ; then ...

and

if [ IsServerStarted -eq 0 ] ; then ...

Seems to me that these two statements should be equivalent? Strangely the second statement is always true.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
sixtyfootersdude
  • 25,859
  • 43
  • 145
  • 213
  • 1
    @skaaffman changed the tag from bourne to bash. Why? Isn't Bourne a subset of bash? – sixtyfootersdude Apr 23 '10 at 14:37
  • Bourne is an ancient shell from the 1970s nobody uses anymore -- and it is **not** a strict subset of bash (for example, Bourne allows `^` as a pipe character, whereas in modern POSIX shells, bash included, only `|` works). On modern systems, `/bin/sh` is guaranteed to be a shell compliant with POSIX sh, a newer specification heavily influenced by ksh, which is a formerly-commercial shell that took inspiration from Bourne. So there's a long and twisty road back to Bourne from modern shells, but it's not something anyone ever uses today; even 20 years ago, only Solaris still shipped it. – Charles Duffy Sep 26 '20 at 01:26
  • ...so it's correct to say POSIX sh and bash are "Bourne-family" shells, but they're not actually Bourne-compatible -- not all Bourne code will run on them. (And writing code that behaves correctly with pre-POSIX Bourne also requires a bunch of extra work to deal with bugs in ancient versions of `test`/`[` -- when one gets back into the pre-POSIX world, some of the `"x$foo"` idioms actually have a reason to exist). – Charles Duffy Sep 26 '20 at 01:32

2 Answers2

9

The following runs the shell function or executable in $PATH named IsServerStarted, and if its exit code is 0 (i.e. true), runs the then branch. If such a function or executable does not exist, the exit code will be non-0 (i.e. false) and the then branch will be skipped.

if IsServerStarted ; then ...

The following has [ (aka test) check whether IsServerStarted is an integer equal to 0, which (IsServerStarted not even containing a single digit) is always false. Thus, [ exits with a non-0 (i.e. false) code and the then branch is always skipped.

if [ IsServerStarted -eq 0 ] ; then ...
ndim
  • 35,870
  • 12
  • 47
  • 57
0

Actually, the second one will give an error complaining that "IsServerStarted" is not a valid integer. It's considered a string constant so something like

var="IsServerStarted"
if [ IsServerStarted == "$var" ] ; then

would succeed (or fail if it wasn't equal).

ndim is correct regarding the executable or function in the first example you gave.

A couple more variations to consider:

if $IsServerStarted ; then ...

In that one, the if is evaluated based on the return value of a command (executable or function) that is contained in the variable IsServerStarted. So you could set IsServerStarted=true and then the if would succeed since true is a shell builtin that always returns true. You could set IsServerStarted='grep popsicle freezer' and theif` would pass or fail depending on whether you were out of treats.

if [ $IsServerStarted -eq 0 ]; then ...

This simply tests whether the variable is equal to zero. If it's not a valid integer it will cause an error message.

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439