I would have done this as a comment to support James Ko but didn't have the rep to comment or publicly up vote.
The issue here is that the [] brackets are notation for doing a comparison test such as value or string equality.
String truthiness in bash for an empty string is ""
(empty string) evaluates to false (return value 1) and any non empty string "false" "true" or "bob's your uncle" evaluates to true (return value 0).
You can prove this to yourself with:
if [ "foo" ]; then
echo true is $?;
else
echo false is $?;
fi
The $?
above is a special variable that holds the last commands exit status (0 success, and any > 0 for error code) and will output true is 0
. You can replace "foo"
with anything you want and the result will be the same except if you replace it with an empty string ""
or ''
in which case it will evaluate the else condition and output false is 1
.
When using the [] brackets the internal statement such as ! $phone_missing is evaluated and then returns a 0
for true or 1
for false to the if control statement. Since the bracket evaluates string and value comparisons the $phone_missing is first expanded to the non empty string "false" which is evaluated by the [] as non empty string (or true) and then the ! inverts the result which results in the if statement getting a false (or return value 1) and it skips the conditional body executing the else statement if present.
As James Ko said the notation would be to just pass the variable holding your 'boolean' to the if control statement. Note that in bash a boolean true and false must be lower case as in:
bool_true=true
bool_false=false
Any other case will evaluate as strings and not boolean.
So using your example and James Ko's answer it would be:
phone_missing=false
echo "missing $phone_missing"
if ! $phone_missing
then
echo "Lost phone at $readabletime"
$phone_missing=true
fi
or as I prefer for readability (syntactically the same and James Ko's)
phone_missing=false
echo "missing $phone_missing"
if ( ! $phone_missing ); then
echo "Lost phone at $readabletime"
$phone_missing=true
fi
Other answers such as by Alexios are literally checking the string content. So that either of the following would result in false:
phone_missing=false
if [ "$phone_missing" != false ]; then
echo "phone_missing is not 'false' (but may be non-true, too)"
fi
if [ "$phone_missing" == true ]; then
echo "phone_missing is not 'false' (but may be non-true, too)"
fi
if [ "$phone_missing" == Bobs_your_uncle ]; then
echo "phone_missing is not 'false' (but may be non-true, too)"
fi