For example, when you run the following shell script:
foo="example"
if [ -o $foo ]; then
foo="true"
echo $foo
fi
The result is false and nothing is returned.
but If the value of foo is null
foo=" "
if [ -o $foo ]; then
foo="true"
echo $foo
fi
Returns true value.
The operation foo = "example" if [ $foo -o $foo ] in shell scripts is understandable.(I understand that the value is true.)
However, if foo = "abc" if [ -o $foo ], I understand it as null or true ($foo value).
The result is false, contrary to my expectation.
What is the reason for this?
CodePudding user response:
Whenever you don't quote a variable, and the variable is empty, or only white space (what is in $IFS), the command doesn't see that at all. so test -o $foo is the same as test -o
I don't think there's a particularly good reason it returns true, what you have done is pathological and makes no sense. What you need to do is double quote the variable, that guarantees that test can see there is something there, and then it will do something rational with it. As a general rule, always double quote stuff that you pass to test, just in case it is empty.
CodePudding user response:
Reading the bash source code:
Case 1a: foo="example"; [ -o $foo ]
→ [ -o example ]
Case 1b: foo=""; [ -o "$foo" ]
→ [ -o □ ]
- using □ to denote that argument is empty string
- parsed as two arguments
- first argument (
-o
) matches unary operator "find_option_o_value" - second argument is not a valid option name
- result: false (not found)
- note: when second argument is a valid option name, the return value will indicate if the option is set (true ⇒ enabled, false ⇒ disabled)
Case 2a: foo=" "; [ -o $foo ]
→ [ -o ]
Case 2b: foo=" "; [ $foo -o $foo ]
→ [ -o ]
- parsed as one argument
- argument (
-o
) is non-null - result: true
Case 3: foo=""; [ "$foo" -o "$foo" ]
→ [ □ -o □ ]
- using □ to denote that argument is empty string
- parsed as three arguments
- second argument is ANDOR operator
- neither first nor third argument is non-null
- result: false
Case 4: foo=""; [ "$foo" -o $foo ]
→ [ □ -o ]
- using □ to denote that argument is empty string
- parsed as two arguments
- first argument is not a unary operator
- result: false (syntax error)