Как объявить и использовать логические переменные в оболочке script?

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

variable=$false

variable=$true

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

if [ $variable ]

if [ !$variable ]

Ответ 1

Исправленный ответ (12 февраля 2014 г.)

the_world_is_flat=true
# ...do something interesting...
if [ "$the_world_is_flat" = true ] ; then
    echo 'Be careful not to fall off!'
fi

Оригинальный ответ

Предостережения: fooobar.com/questions/14195/...

the_world_is_flat=true
# ...do something interesting...
if $the_world_is_flat ; then
    echo 'Be careful not to fall off!'
fi

От: Использование логических переменных в Bash

Причина, по которой первоначальный ответ включен сюда, заключается в том, что комментарии до пересмотра 12 февраля 2014 года относятся только к первоначальному ответу, и многие комментарии неверны, когда связаны с пересмотренным ответом. Например, комментарий Денниса Уильямсона о bash builtin true от 2 июня 2010 г. относится только к первоначальному ответу, а не к пересмотренному.

Ответ 2

TL; DR

bool=true

if [ "$bool" = true ]

Проблемы с Мику (оригинал)

Я не рекомендую принятый ответ 1. Его синтаксис хорош, но у него есть некоторые недостатки.

Скажем, у нас есть следующее условие.

if $var; then
  echo 'Muahahaha!'
fi

В следующих случаях 2 это условие оценивается как истинное и выполняет вложенную команду.

# Variable var not defined beforehand. Case 1
var=''  # Equivalent to var="".        Case 2
var=    #                              Case 3
unset var  #                           Case 4
var='<some valid command>'  #          Case 5

Как правило, вы хотите, чтобы ваше условие оценивалось как true, когда ваша "логическая" переменная var в этом примере явно установлена в true. Все остальные случаи опасно вводят в заблуждение!

Последний случай (# 5) особенно капризен, потому что он выполнит команду, содержащуюся в переменной (поэтому условие оценивается как истинное для допустимых команд 3, 4).

Вот безобидный пример:

var='echo this text will be displayed when the condition is evaluated'
if $var; then
  echo 'Muahahaha!'
fi

# Outputs:
# this text will be displayed when the condition is evaluated
# Muahahaha!

Заключение в кавычки ваших переменных более безопасно, например, if "$var"; then if "$var"; then. В вышеуказанных случаях вы должны получить предупреждение о том, что команда не найдена. Но мы все еще можем сделать лучше (см. Мои рекомендации внизу).

Также см. Объяснение Mike Holt оригинального ответа Miku.

Проблемы с ответом Hbar

Этот подход также имеет неожиданное поведение.

var=false
if [ $var ]; then
  echo "This won't print, var is false!"
fi

# Outputs:
# This won't print, var is false!

Можно ожидать, что вышеприведенное условие оценивается как ложное, поэтому никогда не выполняете вложенный оператор. Сюрприз!

Заключение в кавычки значения ("false"), цитирование переменной ("$var") или использование test или [[ вместо [ ,] не имеют значения.

Что я рекомендую:

Вот способы, которые я рекомендую вам проверить ваши "логические значения". Они работают как положено.

bool=true

if [ "$bool" = true ]; then
if [ "$bool" = "true" ]; then

if [[ "$bool" = true ]]; then
if [[ "$bool" = "true" ]]; then
if [[ "$bool" == true ]]; then
if [[ "$bool" == "true" ]]; then

if test "$bool" = true; then
if test "$bool" = "true"; then

Они все в значительной степени эквивалентны. Вам нужно будет набрать на несколько клавиш больше, чем в других ответах 5, но ваш код будет более защищенным.


Сноски

  1. Ответ Miku с тех пор был отредактирован и больше не содержит (известных) недостатков.
  2. Не исчерпывающий список.
  3. Действительная команда в этом контексте означает команду, которая существует. Неважно, если команда используется правильно или неправильно. Например, man woman все равно будет считаться действительной командой, даже если такой страницы не существует.
  4. Для недействительных (несуществующих) команд Bash будет просто жаловаться, что команда не найдена.
  5. Если вы заботитесь о длине, первая рекомендация самая короткая.

Ответ 3

Похоже, что здесь есть некоторое недопонимание о встроенной в Bash true, а точнее, о том, как Bash расширяет и интерпретирует выражения в скобках.

Код в ответе miku не имеет абсолютно никакого отношения ни к встроенной в Bash true, ни к /bin/true, ни к какому-либо другому варианту команды true. В этом случае true - это не более чем простая символьная строка, и никакой вызов true команды/встроенной команды никогда не выполняется ни с помощью присваивания переменной, ни с помощью вычисления условного выражения.

Следующий код функционально идентичен коду в ответе miku:

the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
    echo 'Be careful not to fall off!'
fi

Единственное отличие здесь состоит в том, что сравниваются четыре символа: "у", "е", "а" и "ч" вместо "т", "г", "у" и "е". Это. Не было предпринято никаких попыток вызвать команду или встроенную функцию с именем yeah, и при этом (в примере miku) не происходит какой-либо специальной обработки, когда Bash анализирует токен true. Это просто строка, причем совершенно произвольная.

Обновление (2014-02-19): После перехода по ссылке в ответе miku, теперь я вижу, откуда происходит некоторая путаница. Ответ Miku использует одиночные скобки, но фрагмент кода, на который он ссылается, не использует скобки. Это просто:

the_world_is_flat=true
if $the_world_is_flat; then
  echo 'Be careful not to fall off!'
fi

Оба фрагмента кода будут вести себя одинаково, но скобки полностью изменят то, что происходит под капотом.

Вот что Bash делает в каждом случае:

Без скобок:

  1. Разверните переменную $the_world_is_flat до строки "true".
  2. Попытайтесь проанализировать строку "true" как команду.
  3. Найдите и выполните команду true (встроенную или /bin/true, в зависимости от версии Bash).
  4. Сравните код завершения команды true (который всегда равен 0) с 0. Напомним, что в большинстве оболочек код выхода 0 указывает на успех, а все остальное указывает на сбой.
  5. Поскольку код выхода был 0 (успех), выполните оператор if then предложение

Скобки:

  1. Разверните переменную $the_world_is_flat до строки "true".
  2. Проанализируйте полностью раскрытое условное выражение, которое имеет вид string1 = string2. Оператор = является оператором сравнения строк bash. Так...
  3. Сделайте сравнение строк на "true" и "true".
  4. Да, две строки были одинаковыми, поэтому значение условного выражения истинно.
  5. Выполните предложение if then предложение.

Код без скобок работает, потому что команда true возвращает код завершения 0, который указывает на успех. Код в квадратных скобках работает, потому что значение $the_world_is_flat идентично строковому $the_world_is_flat true в правой части =.

Просто чтобы понять суть, рассмотрим следующие два фрагмента кода:

Этот код (если он запускается с правами root) перезагрузит ваш компьютер:

var=reboot
if $var; then
  echo 'Muahahaha! You are going down!'
fi

Этот код просто печатает "Хорошая попытка". Команда перезагрузки не вызывается.

var=reboot
if [ $var ]; then
  echo 'Nice try.'
fi

Обновление (2014-04-14) Чтобы ответить на вопрос в комментариях относительно разницы между = и ==: AFAIK, нет никакой разницы. Оператор == является синонимом Bash для =, и, насколько я видел, они работают одинаково во всех контекстах.

Однако обратите внимание, что я специально говорю об операторах сравнения строк = и == используемых в тестах [ ] или [[ ]]. Я не предполагаю, что = и == взаимозаменяемы везде в bash.

Например, вы, очевидно, не можете назначать переменные с помощью ==, например, var=="foo" (технически вы можете сделать это, но значение var будет равно "=foo", потому что Bash не видит Здесь оператор ==, он видит оператор = (присваивание), за которым следует буквальное значение ="foo", которое просто становится "=foo").

Кроме того, хотя = и == взаимозаменяемы, вы должны помнить, что как эти тесты работают, зависит от того, используете ли вы их внутри [ ] или [[ ]], а также от того, заключены ли в кавычки операнды или нет. Вы можете прочитать больше об этом в Advanced Bash Scripting Guide: 7.3 Другие операторы сравнения (прокрутите вниз до обсуждения = и ==).

Ответ 4

Используйте арифметические выражения.

#!/bin/bash

false=0
true=1

((false)) && echo false
((true)) && echo true
((!false)) && echo not false
((!true)) && echo not true

Вывод:

верно
  не false

Ответ 5

Короче:

В bash нет логических значений

Что действительно имеет bash, так это булевы выражения с точки зрения сравнения и условий. Тем не менее, то, что вы можете объявить и сравнить в bash, это строки и числа. Это.

Везде, где вы видите true или false в bash, это либо строка, либо команда/встроенная команда, которая используется только для кода выхода.

Этот синтаксис...

if true; then ...

по сути...

if COMMAND; then ...

Условие истинно, когда команда возвращает код выхода 0. true и false являются встроенными функциями Bash, а иногда и автономными программами, которые ничего не делают, кроме как возвращая соответствующий код завершения.

Условие выше эквивалентно:

COMMAND && ...

При использовании квадратных скобок или команды test вы полагаетесь на код завершения этой конструкции. Имейте в виду, что [ ] и [[ ]] также являются просто командами/встроенными командами, как и любые другие. Так...

if [[ 1 == 1 ]]; then echo yes; fi

соответствует

if COMMAND; then echo yes; fi

и COMMAND здесь [[ 1 == 1 ]]

Конструкция if..then..fi - это просто синтаксический сахар. Вы всегда можете просто запустить команды, разделенные двойным амперсандом, для того же эффекта:

[[ 1 == 1 ]] && echo yes

При использовании true и false в этих конструкциях тестирования вы фактически передаете только команду "true" или "false" команде тестирования. Вот пример:

Хотите верьте, хотите нет, но все эти условия дают один и тот же результат:

if [[ false ]]; then ...
if [[ "false" ]]; then ...
if [[ true ]]; then ...
if [[ "true" ]]; then ...

TL; DR; всегда сравнивайте со строками или числами

Чтобы это было понятно будущим читателям, я бы рекомендовал всегда использовать кавычки вокруг true и false:

ДЕЛАТЬ

if [[ "${var}" == "true" ]]; then ...
if [[ "${var}" == "false" ]]; then ...
if [[ -n "${var:-}" ]]; then echo "var is not empty" ...

НЕ

if [ ... ]; then ...  # always use double square brackets in bash!
if [[ "${var}" ]]; then ...  # this is not as clear or searchable as -n
if [[ "${var}" != true ]]; then ...  # creates impression of booleans
if [[ "${var}" -eq "true" ]]; then ...  # '-eq' is for numbers and doesn't read as easy as '=='

Может быть

if [[ "${var}" != "true" ]]; then ...  # creates impression of booleans. Can be used for strict checking of dangerous operations. This condition is false for anything but the literal string "true". 

Ответ 6

Давным-давно, когда все, что у нас было, было sh, booleans, где обрабатывается, полагаясь на соглашение программы test, где test возвращает статус ложного выхода, если запускается без аргументов. Это позволяет думать о переменной, которая не задана как false, а переменная установлена ​​на любое значение как значение true. Сегодня тест построен на bash и обычно известен по его одному псевдониму символа [ (или исполняемому файлу для использования в оболочках, лишенных его, как отмечает дольмен):

FLAG="up or <set>"

if [ "$FLAG" ] ; then 
    echo 'Is true'
else 
    echo 'Is false'
fi

# unset FLAG
#    also works
FLAG=

if [ "$FLAG" ] ; then
    echo 'Continues true'
else
    echo 'Turned false'
fi

Из-за цитирования соглашения script авторы предпочитают использовать составную команду [[, которая имитирует test, но имеет более хороший синтаксис: переменные с пробелами не нужно указывать, можно использовать && и || как логические операторы со странным приоритетом, и нет ограничений POSIX на количество терминов.

Например, чтобы определить, установлен ли FLAG, а COUNT - число больше 1:

FLAG="u p"
COUNT=3

if [[ $FLAG  && $COUNT -gt '1' ]] ; then 
    echo 'Flag up, count bigger than 1'
else 
    echo 'Nope'
fi

Этот материал может запутать, когда нужны пробелы, строки с нулевой длиной и нулевые переменные, а также когда ваш script должен работать с несколькими оболочками.

Ответ 7

Как объявить и использовать логические переменные в оболочке script?

В отличие от многих других языков программирования, Bash не разделяет свои переменные по типу. [1]

Итак, ответ довольно ясен. В bash нет boolean variable. Однако:

Используя оператор declare, мы можем ограничить присвоение значения переменным. [2]

#!/bin/bash
declare -ir BOOL=(0 1) #remember BOOL can't be unset till this shell terminate
readonly false=${BOOL[0]}
readonly true=${BOOL[1]}
#same as declare -ir false=0 true=1
((true)) && echo "True"
((false)) && echo "False"
((!true)) && echo "Not True"
((!false)) && echo "Not false"

Параметр r в declare и readonly используется для явного указания, что переменные только для чтения. Надеюсь, что цель понятна.

Ответ 8

Вместо того, чтобы подделывать логическое значение и оставлять ловушку для будущих читателей, почему бы просто не использовать лучшее значение, чем true и false?

Например:

build_state=success
if something-horrible; then
  build_state=failed
fi

if [[ "$build_state" == success ]]; then
  echo go home, you are done
else
  echo your head is on fire, run around in circles
fi

Ответ 9

POSIX (интерфейс переносимой операционной системы)

Я здесь скучаю по ключевому моменту - мобильности. Вот почему мой заголовок имеет POSIX сам по себе.

По сути, все проголосовавшие ответы верны, за исключением того, что они слишком BASH -specific.

В основном, я только хочу добавить больше информации о переносимости.


  1. Скобки [ и ] как в [ "${var}" = true ], не нужны, их можно опустить и напрямую использовать команду test:

    test "${var}" = true && CodeIfTrue || CodeIfFalse
    

    Обратите внимание, что я больше не рекомендую это, поскольку это медленно устаревает.

  2. Представьте, что эти слова означают " true и " false для оболочки, проверьте сами:

    echo $(( true ))
    
    0
    
    echo $(( false ))
    
    1
    

    Но используя кавычки:

    echo $(( "true" ))
    
    bash: "true": syntax error: operand expected (error token is ""true"")
    sh (dash): sh: 1: arithmetic expression: expecting primary: ""true""
    

    То же самое касается:

    echo $(( "false" ))
    

    Оболочка не может интерпретировать это, кроме строки. Я надеюсь, что вы получаете представление о том, как хорошо использовать правильное ключевое слово без кавычек.

    Но никто не сказал это в предыдущих ответах.

  3. Что это значит? Ну, несколько вещей.

    • Вы должны привыкнуть к тому, что логические ключевые слова на самом деле обрабатываются как числа, то есть true= 0 и false= 1, помните, что все ненулевые значения обрабатываются как false.

    • Так как они обрабатываются как числа, вы должны обращаться с ними так же, т.е. если вы определяете переменную, скажем:

      var_bool=true
      echo "${var_bool}"
      
       true
      

      Вы можете создать противоположное значение с помощью:

      var_bool=$(( 1 - ${var_bool} ))
      echo "${var_bool}"
      
      1
      

      Как вы сами видите, оболочка печатает true строку в первый раз, когда вы ее используете, но с тех пор все работает через число 0 представляющее true или 1 представляющее false, соответственно.


Наконец, что вы должны делать со всей этой информацией

  • Во-первых, одна хорошая привычка будет назначать 0 вместо true; 1 вместо false.

  • Вторая хорошая привычка - проверять, равна ли переменная нулю:

    if [ "${var_bool}" -eq 0 ]; then YourCodeIfTrue; else YourCodeIfFalse; fi
    

Ответ 10

За Билла Паркера проголосовали, потому что его определения противоположны обычному соглашению о коде. Обычно true определяется как 0, а false определяется как ненулевой. 1 будет работать для ложного, как и 9999 и -1. То же самое с возвращаемыми значениями функции - 0 - успех, а все ненулевое значение - сбой. Извините, у меня пока нет авторитета на улице, чтобы голосовать или отвечать ему напрямую.

Bash рекомендует теперь использовать двойные скобки вместо привычных скобок, и ссылка, которую дал Майк Холт, объясняет различия в том, как они работают. 7.3. Другие операторы сравнения

С одной стороны, -eq является числовым оператором, поэтому наличие кода

#**** NOTE *** This gives error message *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

выдаст сообщение об ошибке, ожидая целочисленное выражение. Это относится к любому параметру, поскольку ни одно из них не является целочисленным значением. Тем не менее, если мы заключим в него двойные скобки, он не выдаст сообщение об ошибке, но приведет к неправильному значению (ну, в 50% возможных перестановок). Он будет оцениваться как [[0 -eq true]] = success, но также как [[0 -eq false]] = success, что неверно (хммм.... как насчет того, что встроенная функция является числовым значением?),

#**** NOTE *** This gives wrong output *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then

Существуют и другие перестановки условного выражения, которые также дадут неправильный вывод. По сути, все (кроме состояния ошибки, указанного выше), которое устанавливает переменную в числовое значение и сравнивает ее со встроенной функцией истина/ложь, или устанавливает переменную со встроенной истиной/ложью и сравнивает ее с числовым значением. Кроме того, все, что устанавливает переменную во встроенное значение true/false и выполняет сравнение, используя -eq. Поэтому избегайте -eq для логических сравнений и избегайте использования числовых значений для логических сравнений. Вот краткое изложение перестановок, которые дадут неверные результаты:

#With variable set as an integer and evaluating to true/false
#*** This will issue error warning and not run: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

#With variable set as an integer and evaluating to true/false
#*** These statements will not evaluate properly: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
#
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" == true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then


#With variable set as an true/false builtin and evaluating to true/false
#*** These statements will not evaluate properly: *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = 0 ]; then
#
if [[ "${The_world_is_flat}" = 0 ]]; then
#
if [ "${The_world_is_flat}" == 0 ]; then
#
if [[ "${The_world_is_flat}" == 0 ]]; then

Итак, теперь к тому, что работает. Используйте встроенные true/false для сравнения и оценки (как отметил Майк Хант, не заключайте их в кавычки). Затем используйте одинарный или двойной знак равенства (= или ==) и одинарные или двойные скобки ([] или [[]]). Лично мне нравится знак двойного равенства, потому что он напоминает мне о логических сравнениях в других языках программирования, и двойные кавычки только потому, что я люблю печатать. Итак, эти работы:

#With variable set as an integer and evaluating to true/false
#*** These statements will work properly: *****
#
The_world_is_flat=true/false;
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then

Там у вас есть это.

Ответ 11

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

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

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

человек Баш:

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

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

Ответ 12

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

Если вы установите для переменной значение true, в условном 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

Ответ 13

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

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

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

snapshotEvents=true

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

и чтобы все были счастливы, я проверил:

snapshotEvents=false

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

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

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

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

Ответ 14

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

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

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

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

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

Ответ 15

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

temp1=true
temp2=false

if [ "$temp1" = true ] || [ "$temp2" = true ]
then
    echo "Do something." 
else
    echo "Do something else."
fi

Ответ 16

Вот реализация с короткими руками, 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"

Ответ 17

Вы можете использовать GFlags: https://gflags.github.io/gflags/

Это дает вам возможность определить: DEFINE_bool

Пример:

DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");

Из командной строки вы можете определить:

sh script.sh --bigmenu
sh script.sh --nobigmenu # False

Ответ 18

Альтернатива - использовать функцию

is_ok(){ :;}
is_ok(){ return 1;}
is_ok && echo "It OK" || echo "Something wrong"

Определение функции менее интуитивно понятно, но проверить возвращаемое значение очень просто.

Ответ 19

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
    

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

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