Тернарный оператор (? :) в Баш - PullRequest
353 голосов
/ 17 октября 2010

Есть ли способ сделать что-то вроде этого

int a = (b == 5) ? c : d;

, используя Bash?

Ответы [ 14 ]

393 голосов
/ 17 октября 2010

троичный оператор ? : - это краткая форма if/else

case "$b" in
 5) a=$c ;;
 *) a=$d ;;
esac

Или

 [[ $b = 5 ]] && a="$c" || a="$d"
297 голосов
/ 17 октября 2010

Код:

a=$([ "$b" == 5 ] && echo "$c" || echo "$d")
125 голосов
/ 02 октября 2012

Если условие просто проверяет, установлена ​​ли переменная, существует даже более короткая форма:

a=${VAR:-20}

присвоит a значение VAR, если установлено VAR, в противном случае ему будет присвоено значение по умолчанию 20 - это также может быть результатом выражения.

Как отмечает Алекс в комментарии, этот подход технически называется «Расширение параметров».

58 голосов
/ 04 августа 2014
if [ "$b" -eq 5 ]; then a="$c"; else a="$d"; fi

Выражение cond && op1 || op2, предлагаемое в других ответах, имеет присущую ошибку: если op1 имеет ненулевой статус выхода, op2 молча становится результатом; ошибка также не будет обнаружена в режиме -e. Таким образом, это выражение безопасно использовать только в том случае, если op1 никогда не может завершиться ошибкой (например, :, true, если встроенное, или присвоение переменной без каких-либо операций, которые могут завершиться неудачей (например, вызовы деления и OS)).

Обратите внимание на кавычки "". Первая пара предотвратит синтаксическую ошибку, если $b пусто или имеет пробел. Другие будут препятствовать переводу всех пробелов в одиночные пробелы.

41 голосов
/ 18 октября 2010
(( a = b==5 ? c : d )) # string + numeric
29 голосов
/ 04 апреля 2013
[ $b == 5 ] && { a=$c; true; } || a=$d

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

11 голосов
/ 23 мая 2014

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

VARIABLE=`[ test ] && echo VALUE_A || echo VALUE_B`

Просто мысль. :)

10 голосов
/ 14 июня 2011

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

let a=b==5?c:d;

Естественно, это работает только для присвоения переменных;он не может выполнять другие команды.

7 голосов
/ 19 февраля 2016

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

Примеры

$ tern 1 YES NO                                                                             
YES

$ tern 0 YES NO                                                                             
NO

$ tern 52 YES NO                                                                            
YES

$ tern 52 YES NO 52                                                                         
NO

и может использоваться в сценарии следующим образом:

RESULT=$(tern 1 YES NO)
echo "The result is $RESULT"

крачка

function show_help()
{
  echo ""
  echo "usage: BOOLEAN VALUE_IF_TRUE VALUE_IF_FALSE {FALSE_VALUE}"
  echo ""
  echo "e.g. "
  echo ""
  echo "tern 1 YES NO                            => YES"
  echo "tern 0 YES NO                            => NO"
  echo "tern "" YES NO                           => NO"
  echo "tern "ANY STRING THAT ISNT 1" YES NO     => NO"
  echo "ME=$(tern 0 YES NO)                      => ME contains NO"
  echo ""

  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$3" ]
then
  show_help
fi

# Set a default value for what is "false" -> 0
FALSE_VALUE=${4:-0}

function main
{
  if [ "$1" == "$FALSE_VALUE" ]; then
    echo $3
    exit;
  fi;

  echo $2
}

main "$1" "$2" "$3"
6 голосов
/ 31 декабря 2017

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

    [ $numVar == numVal ] && resVar="Yop" || resVar="Nop"

Or

    resVar=$([ $numVar == numVal ] && echo "Yop" || echo "Nop")

Or

    (( numVar == numVal ? (resVar=1) : (resVar=0) ))
...