Я бы сделал это как комментарий, чтобы поддержать Джеймса Ко, но у меня не было представителя, чтобы комментировать или публично проголосовать.
Проблема здесь в том, что скобки [] являются обозначением для выполнения сравнительного теста, такого как равенство значений или строк.
Истинность строки в bash для пустой строки равна ""
(пустая строка) оценивается как ложь (возвращаемое значение 1), а любая непустая строка "ложь", "истина" или "Боб, твой дядя" оценивает в истину (возвращаемое значение 0).
Вы можете убедиться в этом сами с помощью:
if [ "foo" ]; then
echo true is $?;
else
echo false is $?;
fi
$?
выше - это специальная переменная, которая содержит статус выхода последней команды (0 успешных и любое> 0 для кода ошибки) и будет выводить истинно 0
. Вы можете заменить "foo"
чем угодно, и результат будет таким же, за исключением того, что вы замените его пустой строкой ""
или ''
в в этом случае он оценит условие else и выведет false - 1
.
При использовании квадратных скобок [] внутренний оператор, например! $ phone_missing вычисляется и затем возвращает 0
для истины или 1
для ложного оператора if. Поскольку скобка оценивает сравнение строк и значений, $ phone_missing сначала расширяется до непустой строки «false», которая оценивается [] как непустая строка (или истина), а затем! инвертирует результат, который приводит к тому, что оператор if получает ложь (или возвращает значение 1), и пропускает условное тело, выполняющее оператор else, если он присутствует.
Как сказал Джеймс Ко, запись будет состоять в том, чтобы просто передать переменную, содержащую ваше «логическое» значение, в управляющий оператор if. Обратите внимание , что в bash логические значения true и false должны быть в нижнем регистре, как в: bool_true = true bool_false = false Любой другой регистр будет оцениваться как строки а не логическое.
Итак, используя ваш пример и ответ Джеймса Ко, это будет:
phone_missing=false
echo "missing $phone_missing"
if ! $phone_missing
then
echo "Lost phone at $readabletime"
$phone_missing=true
fi
или, как я предпочитаю для удобочитаемости (синтаксически то же самое и у Джеймса Ко)
phone_missing=false
echo "missing $phone_missing"
if ( ! $phone_missing ); then
echo "Lost phone at $readabletime"
$phone_missing=true
fi
Другие ответы, такие как Alexios, буквально проверяют содержимое строки. Так что любой из следующих результатов приведет к ложному результату:
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