Как построить условное задание в bash? - PullRequest
49 голосов
/ 14 марта 2010

Я ищу способ построения условных заданий в bash:

В Java это выглядит так:

int variable= (condition) ? 1 : 0;

Ответы [ 8 ]

58 голосов
/ 14 марта 2010

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

: ${VAR:="default"}

Да, строка начинается с ':'. Я использую это в сценариях оболочки, так что я могу переопределять переменные в ENV или использовать значение по умолчанию.

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

49 голосов
/ 14 марта 2010

Согласно комментарию Джонатана:

variable=$(( 1 == 1 ? 1 : 0 ))  

EDIT:

Я изменил исходный ответ, который просто echo имел значение оператора условия, на самом деле он не показывал никакого назначения.

23 голосов
/ 14 марта 2010
myvar="default" && [[ <some_condition_is_true> ]]  && myvar="non-default"

реальные примеры:

DELIM="" && [[ "$APP_ENV_RESOLVED" != "" ]] && DELIM=$INNER_DELIM

Условие также может быть "((...))":

filepath=/proc/drbd && (( $# > 0 )) && filepath=$1
18 голосов
/ 09 марта 2016

В дополнение к другим более общим ответам (особенно в соответствии с комментарием Джонатана и более общим ответом Кевина [который также поддерживает строки]), я хотел бы добавить следующие два решения:


установка переменной либо 0, либо 1 в зависимости от условия:

(как показывает пример вопроса.)

Общая форма будет читать

(condition); variable=$?;

, где $variable означает, что 0 или 1, а condition может быть любым допустимым условным выражением .

например. проверка переменной ...

[[ $variableToCheck == "$othervariable, string or number to match" ]]
variable=$?

... или проверка существования файла ...

[ -f "$filepath" ]
fileExists=$?

... или проверка числового значения $myNumber:

(( myNumber >= 1000000000 ))
is_huge_number=$?


Преимущества этого решения в том, что


Обратите внимание: В Bash специальная переменная $? всегда содержит код завершения ранее выполненного оператора (или блока операторов; для получения более подробной информации см. man bash ). Таким образом, положительный результат обычно представлен значением 0, а не 1 (см. Мой комментарий ниже , спасибо Assimilater за , указывающим его ). Таким образом, если условие истинно (например, [[2 eq 2]]), то $?=0.

Если вместо этого вам нужно 0 или 1 в вашей переменной (например, для печати или выполнения математических вычислений), тогда вам нужно использовать логическое отрицание, используя ведущий восклицательный знак (как указано GypsySpellweaver в комментариях ниже ): ( ! condition ); variable=$? или ! ( condition ); variable=$?. (Однако читаемость с точки зрения того, что происходит, может быть немного менее очевидна.)

Другим возможным решением от Джонатана было бы variable=$(( 1 == 1 ? 1 : 0 )) - что, однако, создает подоболочку.

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


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

Как и в большинстве других ответов, он может быть адаптирован следующим образом:

(condition) \
    && variable=true \
    || variable=false

например, как в

[[ $variableToCheck == "$othervariable, string or number to match" ]] \
    && variable="$valueIfTrue" \
    || variable="$valueIfFalse"

или получить 1 при положительном чеке и 0 при неудаче (как в примере с вопросом):

[[ $variableToCheck == "$othervariable, string or number to match" ]] \
    && variable=1 \
    || variable=0

(для последнего примера - как уже упоминалось в примечаниях выше) - то же самое можно достичь с помощью логического отрицания с использованием ведущего восклицательного знака:

[[ ! $variableToCheck == "$othervariable, string or number to match" ]]
variable=$?


Преимущества этого решения в том, что

  • его можно считать немного лучше читаемым , чем ответ Кевина
    myvar="default" && [[ <some_condition_is_true> ]] && myvar="non-default" и
  • $valueIfTrue оценивается условно * только 1124 * при необходимости ,
    , что будет иметь значение в случае, если вы что-то сделаете
    • с побочным эффектом, вроде
      • variable=$((i++)) или
      • { variable=$1; shift; }
    • высокие вычисления, как
      • variable=$(find / -type f -name ListOfFilesWithThisNameOnMySystem)
  • немного короче , чем ответ ghostdog74
    (что, впрочем, замечательно, если у вас несколько условий!)
  • не открывает подоболочку, как в ответе Пьера
  • и как указано выше:
8 голосов
/ 28 января 2016

Я хотел сделать условное присвоение со строками, и я закончил с:

SOWHAT=$([ "$MYVALUE" = "value" ] && echo "YES" || echo "NO")
6 голосов
/ 03 марта 2013

Большие взлеты до @Demosthenex и особенно @Dennis Williamson за самое короткое и простое решение, которое я видел. Оставьте значение bash , чтобы потребовать набор скобок для простого троичного назначения. Ааа, 60-е ! И собрать все это в один пример ...

echo $BASHRULES;             # not defined
                             # no output
: ${BASHRULES:="SCHOOL"}     # assign the variable
echo $BASHRULES              # check it
SCHOOL                       # correct answer
: ${BASHRULES="FOREVER?"}    # notice the slightly different syntax for the conditional assignment
echo $BASHRULES              # let's see what happened!
SCHOOL                       # unchanged! (it was already defined)

Я писал, что давным-давно ... в эти дни я, вероятно, был бы более взволнован таким решением, как ...

PLATFORM=iphonesimulator
OTHERSDK=iphone && [[ $PLATFORM=~os ]]      \
                &&     OTHERSDK+=simulator  \
                ||     OTHERSDK+=os

$OTHERSDKiphoneos

4 голосов
/ 01 мая 2014

Если вы хотите присвоить значение, если переменная не пуста, используйте это:

[ -z "$variable" ] && variable="defaultValue"

Вы можете также поставить друг другу условие на []

3 голосов
/ 14 марта 2010

другой способ

case "$variable" in
  condition ) result=1;;
  *) result=0;;
esac
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...