Понимание булевых операторов в сценарии bash

phone_missing=false echo "missing $phone_missing" if [ ! $phone_missing ] then echo "Lost phone at $readabletime" $phone_missing=true fi 

Я просто не могу обмотать голову вокруг, так глупо, что это может звучать. Линия

 echo "missing $phone_missing" 

echos missing false , я бы очень ожидал утверждения

 if [ ! $phone_missing ] 

чтобы быть истинным и ввести предложение if , но это не так? Что мне здесь не хватает !?

  • Как сопоставить строку в файле, но только если строка находится в первом поле?
  • Лучшая практика использования $? в bash?
  • Как сохранить / dev / stdout целевое местоположение в сценарии bash?
  • Правильный способ использования shebang для bash
  • Проверьте, пуст ли пуст и запустите команду над данными, если это не
  • Как совместить замещение процесса Bash с HERE-документом?
  • Символы, отличные от ASCII, обрабатываются неправильно в командной строке
  • Echo строка с переменной в ней без расширения / оценки
  • 5 Solutions collect form web for “Понимание булевых операторов в сценарии bash”

    $ phone_missing – это строка, которая содержит «false». И непустая строка оценивается как true. См. Также http://www.linuxintro.org/wiki/Babe#empty_strings

    Я часто использую «true» и «false», так как они также являются командами, которые просто возвращают успех и неудачу соответственно. Тогда вы можете сделать

     if "$phone_missing"; then ... 

    Вот один из способов сделать это, сохраняя значения true / 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 true." fi 

    Двойные кавычки вокруг $phone_missing предназначены для защиты от случая, когда переменная phone_missing вообще не определена. Еще одна распространенная идиома для защиты от этого – [ x$phone_missing != xfalse ] , но цитаты кажутся мне более естественными.

    Подсказка находится на странице справки bash для test :

      STRING True if string is not empty. ... ! EXPR True if expr is false. 

    Таким образом, в основном [ $foo ] будет true, если $foo является пустым. Не верно или неверно, просто не пусто. [ ! $foo ] [ ! $foo ] истинно, если $ foo пуст или не определен.

    Вы всегда можете изменить свой код, чтобы просто установить phone_missing на непустое значение, которое будет обозначать true. Если phone_missing не установлен (или пустой – phone_missing="" ), он будет ложным. В противном случае вы должны использовать операторы тестирования строк ( = и != ).

    Другой небольшой проблемой является назначение. У вас это как $phone_missing=true , тогда как это должно быть phone_missing=true (знак доллара).

    Извините, если это немного плотно, это потому, что я есть. Это был долгий день. 🙂

    Я бы сделал это в качестве комментария для поддержки Джеймса Ко, но не имел репутации для комментариев или публичного голосования.

    Проблема здесь в том, что [] скобки являются обозначениями для проведения сравнительного теста, такого как равенство стоимости или строки.

    Строковая правдивость в bash для пустой строки равна "" (пустая строка), которая вычисляется как false (возвращаемое значение 1), а любая непустая строка «false», «true» или «bob's your uncle» оценивается как true (возвращаемое значение 0).

    Вы можете доказать это себе:

      if [ "foo" ]; then echo true is $?; else echo false is $?; fi 

    $? выше – специальная переменная, которая содержит последние данные о статусе выхода команд (0 успешных, а также> 0 для кода ошибки) и выводит значение true is 0 . Вы можете заменить "foo" на что угодно, и результат будет таким же, за исключением случаев, если вы замените его пустой строкой "" или '' в этом случае он будет оценивать условие else, а вывод false is 1 .

    При использовании [] скобок используется внутреннее утверждение типа! $ phone_missing оценивается, а затем возвращает 0 для true или 1 для false для оператора if. Поскольку скобка оценивает сравнение строк и значений, $ phone_missing сначала расширяется до непустой строки «false», которая оценивается как [] как непустая строка (или true), а затем значение! инвертирует результат, который приводит к тому, что оператор if получает ложное значение (или возвращаемое значение 1) и пропускает условное тело, выполняющее оператор else, если он присутствует.

    Поскольку Джеймс Ко сказал, что нотация будет состоять в том, чтобы просто передать переменную, содержащую ваш «логический» в оператор управления if. Обратите внимание, что в bash логическое значение true и false должно быть нижним регистром, например: bool_true = true bool_false = false Любой другой случай будет оцениваться как строки, а не boolean.

    Поэтому, используя ваш пример и ответ Джеймса Ко, это будет:

     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 

    Правильный синтаксис – if ! $bool; then [statements]; fi if ! $bool; then [statements]; fi if ! $bool; then [statements]; fi .

    Пример:

     bool=false if ! $bool; then echo "This is correct!" fi if [ ! $bool ]; then echo "This is wrong!" fi 

    Результат: This is correct!

    Linux и Unix - лучшая ОС в мире.