Nick
Nick

Reputation: 457

Why does sourcing give a syntax error when bash executes the code fine?

The script is quite simple:

#!/bin/bash
if [[ 0 ]]; then
   echo foo
fi

The error manifests as:

$ source ./sample.sh
./sample.sh:2: parse error near `]]'

But notice that bash is able to execute the script just fine:

$ /bin/bash ./sample.sh
foo

$ /bin/bash --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

From the bash docs:

[[ expression ]]
   Return a status of 0 or 1 depending on  the  evaluation  of  the
   conditional  expression expression.  Expressions are composed of
   the primaries described  below  under  CONDITIONAL  EXPRESSIONS.

   ...

CONDITIONAL EXPRESSIONS
   Conditional  expressions  are  used  by the [[ compound command and the
   test and [ builtin commands to test file attributes and perform  string
   and  arithmetic comparisons.  Expressions are formed from the following
   unary or binary primaries.

   ...

   string
   -n string
          True if the length of string is non-zero.

Note that the syntax error manifests with either 0 or "0" as the expression.

Adding an operator (eg, -n) resolves the parse error, but it doesn't seem like it should be necessary from the docs and also doesn't explain why bash evaluates it just fine.

Upvotes: 1

Views: 432

Answers (1)

John Kugelman
John Kugelman

Reputation: 361595

Your shell isn't bash. When you run source ./sample.sh it runs the script in the context of the current shell, whatever that is, ignoring the #!/bin/bash hash-bang line.

By the way, what is if [[ 0 ]] intended to do? It's somewhat nonsensical. [[ 0 ]] is equivalent to [[ -n 0 ]] which checks if 0 is a non-empty string. This is guaranteed to be true.

To write a simple true or false check, I would instead write:

if true; then

or

if false; then

Upvotes: 6

Related Questions