web-dev-qa-db-fra.com

Opérateur ternaire (? :) à Bash

Y a-t-il un moyen de faire quelque chose comme ça

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

en utilisant Bash?

359
En_t8

l'opérateur ternaire ? : n'est qu'une forme abrégée de if/else

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

Ou

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

Code:

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

Si la condition vérifie simplement si une variable est définie, il existe même un formulaire plus court:

a=${VAR:-20}

assignera à a la valeur de VAR si VAR est défini, sinon il lui assignera la valeur par défaut 20 - cela peut aussi être le résultat d'une expression.

Comme le note alex dans le commentaire, cette approche est techniquement appelée "extension de paramètre".

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

L'expression cond && op1 || op2 suggérée dans d'autres réponses comporte un bogue inhérent: si op1 a un statut de sortie non nul, op2 devient automatiquement le résultat; l'erreur ne sera pas non plus interceptée en mode -e. Donc, cette expression n’est sans danger que si op1 ne peut jamais échouer (par exemple, :, true si une fonction intégrée ou une affectation de variable sans aucune opération pouvant échouer (comme la division et le système d’exploitation appels)).

Notez les citations "". La première paire empêchera une erreur de syntaxe si $b est vide ou comporte des espaces. D'autres empêcheront la traduction de tous les espaces blancs en espaces simples.

60
ivan_pozdeev
(( a = b==5 ? c : d )) # string + numeric
41
dutCh
[ $b == 5 ] && { a=$c; true; } || a=$d

Cela évitera d'exécuter la partie après || par accident lorsque le code entre && et || échoue.

29
Sir Athos

Voici une autre option où il vous suffit de spécifier la variable que vous affectez une fois, et peu importe qu'il s'agisse d'une chaîne ou d'un nombre:

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

Juste une pensée. :)

11
Jasonovich

La commande let prend en charge la plupart des opérateurs de base dont on aurait besoin:

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

Naturellement, cela ne fonctionne que pour affecter des variables; il ne peut pas exécuter d'autres commandes.

11
emu

Ce qui suit semble fonctionner pour mes cas d'utilisation:

Exemples

$ tern 1 YES NO                                                                             
YES

$ tern 0 YES NO                                                                             
NO

$ tern 52 YES NO                                                                            
YES

$ tern 52 YES NO 52                                                                         
NO

et peut être utilisé dans un script comme ceci:

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

sterne

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"
7
Brad Parks

Nous pouvons utiliser les trois manières suivantes dans Shell Scripting pour l'opérateur ternaire:

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

Or

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

Or

    (( numVar == numVal ? (resVar=1) : (resVar=0) ))
6
Sujay U N
(ping -c1 localhost&>/dev/null) && { echo "true"; } || {  echo "false"; }
5
wibble

Il existe également une syntaxe très similaire pour les conditions ternaires dans bash:

a=$(( b == 5 ? 123 : 321  ))

Malheureusement, cela ne fonctionne qu'avec des chiffres - pour autant que je sache.

3
Andre Dias

Vous pouvez l'utiliser si vous voulez une syntaxe similaire

a=$(( $((b==5)) ? c : d ))
3
PRIYESH PATEL

Voici quelques options:

1- Utilisez si ensuite sur une seule ligne, c'est possible.

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

2- Ecrivez une fonction comme ceci:

 # 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
}

utiliser le script intérieur comme celui-ci

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

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

3- Inspiré dans la réponse à l'affaire, une utilisation plus flexible et à une ligne est:

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

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

Cela ressemble beaucoup à bonne réponse de Vladimir . Si votre "ternaire" est un cas de "si vrai, chaîne, si faux, vide", alors vous pouvez simplement faire:

$ c="it was five"
$ b=3
$ a="$([[ $b -eq 5 ]] && echo "$c")"
$ echo $a

$ b=5
$ a="$([[ $b -eq 5 ]] && echo "$c")"
$ echo $a
it was five
0
Bruno Bronosky