Как объявить и использовать логические переменные в сценарии оболочки? - PullRequest
795 голосов
/ 02 июня 2010

Я попытался объявить логическую переменную в сценарии оболочки, используя следующий синтаксис:

variable=$false

variable=$true

Это правильно? Кроме того, если бы я хотел обновить эту переменную, я бы использовал тот же синтаксис? Наконец, следующий синтаксис для использования логических переменных в качестве правильных выражений:

if [ $variable ]

if [ !$variable ]

Ответы [ 17 ]

2 голосов
/ 30 июля 2018

Во многих языках программирования логический тип является или реализуется как подтип целого числа, где true ведет себя как 1, а false ведет себя как 0:

Математически , булева алгебра напоминает целочисленную арифметику по модулю 2. Поэтому, если язык не предоставляет родной логический тип, наиболее естественным и эффективным решением является использование целых чисел. Это работает практически с любым языком. Например, в Bash вы можете сделать:

# val=1; ((val)) && echo "true" || echo "false"
true
# val=0; ((val)) && echo "true" || echo "false"
false

человек Баш :

((выражение))

Выражение оценивается в соответствии с правилами, описанными ниже в разделе АРИФМЕТИЧЕСКАЯ ОЦЕНКА. Если значение выражения не равно нулю, возвращаемое состояние равно 0; в противном случае возвращаемое состояние равно 1. Это в точности эквивалентно пустому выражению.

1 голос
/ 17 января 2018

Вот простой пример, который работает для меня:

temp1=true
temp2=false

if [ "$temp1" = true ] || [ "$temp2" = true ]
then
    echo "Do something." 
else
    echo "Do something else."
fi
1 голос
/ 22 сентября 2015

Я нашел, что существующие ответы сбивают с толку.

Лично я просто хочу иметь что-то, что выглядит и работает как C.

Этот фрагмент работает много раз в день на производстве:

snapshotEvents=true

if ($snapshotEvents)
then
    # do stuff if true
fi

и чтобы все были довольны, я проверил:

snapshotEvents=false

if !($snapshotEvents)
then
    # do stuff if false
fi

Который тоже работал нормально.

$snapshotEvents оценивает содержимое значения переменной. Итак, вам нужен $.

Тебе не нужны скобки, я просто нахожу их полезными.

1 голос
/ 09 марта 2018

Вот реализация коротких рук if true.

# Function to test if a variable is set to "true"
_if () {
    [ "${1}" == "true" ] && return 0
    [ "${1}" == "True" ] && return 0
    [ "${1}" == "Yes" ] && return 0
    return 1
}

Пример 1

my_boolean=true

_if ${my_boolean} && {
    echo "True Is True"
} || {
    echo "False Is False"
}

Пример 2

my_boolean=false
! _if ${my_boolean} && echo "Not True is True"
1 голос
/ 15 марта 2019

Мои выводы и предложения немного отличаются от других постов. Я обнаружил, что могу использовать истину / ложь в основном так же, как и на любом «обычном» языке, без предложенного «прыжка с обручем» ... Нет необходимости в [] или явном сравнении строк ... bash, dash и busybox. Я бегал с ней и без нее ... Результаты всегда были одинаковыми. Я не уверен, о чем идет речь в оригинальных топ-постах. Может быть, времена изменились, и это все, что нужно?

Если вы установите переменную на true, она будет иметь значение true в условном выражении. Установите его на false, и оно оценивается как ложное. Очень прямо вперед! Единственное предостережение: переменная UNDEFINED также оценивается как true ! Было бы неплохо, если бы это произошло наоборот, но в этом-то и заключается хитрость - , вам просто нужно явно установить для ваших логических значений значение true или false .

См. Пример bash и результаты ниже. Проверьте сами, если хотите подтвердить ...

#!/bin/sh

#not yet defined...
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

myBool=true
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

myBool=false
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

Урожайность

when set to 
it evaluates to true
when set to true
it evaluates to true
when set to false
it evaluates to false
1 голос
/ 04 марта 2016

Вот улучшение оригинального ответа miku , касающееся Денниса Уильямсона в случае, когда переменная не установлена:

the_world_is_flat=true

if ${the_world_is_flat:-false} ; then
    echo "Be careful not to fall off!"
fi

И проверить, является ли переменная false:

if ! ${the_world_is_flat:-false} ; then
    echo "Be careful not to fall off!"
fi

Что касается других случаев с неприятным содержимым в переменной, это проблема с любым внешним вводом, подаваемым в программу.

Любой внешний вход должен быть проверен, прежде чем доверять ему. Но это подтверждение должно быть сделано только один раз, когда этот вход получен.

Это не должно влиять на производительность программы, делая это при каждом использовании переменной, как Деннис Уильямсон предлагает.

0 голосов
/ 03 октября 2014

Bash действительно путает проблему с подобными [, [[, ((, $(( и т. Д.

Все обработки в кодовых пространствах друг друга. Я предполагаю, что это в основном историческое событие, когда Бэшу иногда приходилось притворяться sh.

В большинстве случаев я могу просто выбрать метод и придерживаться его. В этом случае я склонен объявлять (желательно в общем файле библиотеки, который я могу включить с . в мои фактические сценарии).

TRUE=1; FALSE=0

Затем я могу использовать арифметический оператор (( ... )) для проверки таким образом.

testvar=$FALSE

if [[ -d ${does_directory_exist} ]]
then
    testvar=$TRUE;
fi

if (( testvar == TRUE )); then
    # do stuff because the directory does exist
fi
  1. Вы должны быть дисциплинированными. Ваш testvar должен быть постоянно установлен на $TRUE или $FALSE.

  2. В (( ... )) компараторах вам не нужен предшествующий $, что делает его более читабельным.

  3. Я могу использовать (( ... )), потому что $TRUE=1 и $FALSE=0, то есть числовые значения.

  4. Недостатком является необходимость иногда использовать $:

    testvar=$TRUE
    

    что не так красиво.

Это не идеальное решение, но оно охватывает все случаи, мне нужен такой тест.

...