Тернарный оператор (?:) в Bash

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

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

с помощью Bash?

Ответ 1

тернарный оператор ? : является лишь короткой формой if/else

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

или

 [[ $b = 5 ]] && a="$c" || a="$d"

Ответ 2

код:

a=$([ "$b" == 5 ] && echo "$c" || echo "$d")

Ответ 3

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

a=${VAR:-20}

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

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

Ответ 4

(( a = b==5 ? c : d )) # string + numeric

Ответ 5

[ $b == 5 ] && { a=$c; true; } || a=$d

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

Ответ 6

if [ "$b" -eq 5 ]; then a="$c"; else a="$d"; fi

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

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

Ответ 7

Команда let поддерживает большинство базовых операторов:

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

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

Ответ 8

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

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

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

Ответ 9

(ping -c1 localhost&>/dev/null) && { echo "true"; } || {  echo "false"; }

Ответ 10

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

Примеры

$ tern 1 YES NO                                                                             
YES

$ tern 0 YES NO                                                                             
NO

$ tern 52 YES NO                                                                            
YES

$ tern 52 YES NO 52                                                                         
NO

и может использоваться в script так:

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"

Ответ 11

Вы можете использовать это, если хотите аналогичный синтаксис

a=$(( $((b==5)) ? c : d ))

Ответ 12

Вот несколько вариантов:

1- Используйте, если тогда еще в одной строке, это возможно.

if [[ "$2" == "raiz" ]] || [[ "$2" == '.' ]]; then pasta=''; else pasta="$2"; fi

2- Напишите функцию, подобную этой:

 # Once upon a time, there was an 'iif' function in MS VB ...

function iif(){
  # Echoes $2 if 1,banana,true,etc and $3 if false,null,0,''
  case $1 in ''|false|FALSE|null|NULL|0) echo $3;;*) echo $2;;esac
}

используйте внутри script как это

result=`iif "$expr" 'yes' 'no'`

# or even interpolating:
result=`iif "$expr" "positive" "negative, because $1 is not true"` 

3 Вдохновленный в случае ответа, более гибкое и однострочное использование:

 case "$expr" in ''|false|FALSE|null|NULL|0) echo "no...$expr";;*) echo "yep $expr";;esac

 # Expression can be something like:     
   expr=`expr "$var1" '>' "$var2"`