Reputation: 5350
In shell scripting, I am using ternary operator like this:
(( numVar == numVal ? (resVar=1) : (resVar=0) ))
I watched shell scripting tutorial by Derek Banas and got the above syntax at 41:00 of the video
https://www.youtube.com/watch?v=hwrnmQumtPw&t=73s
The above code works when we assign numbers to resVar
, but if I try to assign a string to resVar
, it always returns 0.
(( numVar == numVal ? (resVar="Yop") : (resVar="Nop") ))
and also tried
resVar=$(( numVar == numVal ? (echo "Yop") : (echo "Nop") ))
So which is the right way to do this?
Upvotes: 6
Views: 10637
Reputation: 357
Running with Gohti's idea to make the script more readable:
#!/bin/bash
declare -a resp='([0]="not safe" [1]="safe")'
temp=70; ok=$(( $temp > 60 ? 1 : 0 ))
printf "The temperature is $temp Fahrenheit, it is ${resp[$ok]} to go outside\n";
temp=20; ok=$(( $temp > 60 ? 1 : 0 ))
printf "The temperature is $temp Fahrenheit, it is ${resp[$ok]} to go outside\n";
Upvotes: 0
Reputation: 46856
Arkadiusz already pointed out that ternary operators are an arithmetic feature in bash, not usable in strings. If you want this kind of functionality in strings, you can always use arrays:
$ arr=(Nop Yop)
$ declare -p arr
declare -a arr='([0]="Nop" [1]="Yop")'
$ numVar=5; numVal=5; resvar="${arr[$((numVar == numVal ? 1 : 0))]}"; echo "$resvar"
Yop
$ numVar=2; numVal=5; resvar="${arr[$((numVar == numVal ? 1 : 0))]}"; echo "$resvar"
Nop
Of course, if you're just dealing with two values that can be in position 0
and 1
in your array, you don't need the ternary; the following achieves the same thing:
$ resvar="${arr[$((numVar==numVal))]}"
Upvotes: 1
Reputation: 12508
You didn't tell us what shell you use but it's possible you use
bash
or something similar. Ternary operator in Bash
works only with numbers as
explained in man bash
under ARITHMETIC EVALUATION
section:
The shell allows arithmetic expressions to be evaluated, under certain circumstances (see the let and declare builtin commands and Arithmetic Expansion). Evaluation is done in fixed-width integers with no check for over- flow, though division by 0 is trapped and flagged as an error. The operators and their precedence, associativity, and values are the same as in the C language. The following list of operators is grouped into levels of equal-precedence operators. The levels are listed in order of decreasing precedence.
(...)expr?expr:expr
conditional operator
And the reason that resVar
is assigned 0
when you use "Yop"
or
"Nop"
is because such string is not a valid number in bash
and
therefore it's evaluated to 0
. It's also explained in man bash
in
the same paragraph:
A null value evaluates to 0.
It's also explained in this Wikipedia article if you find it easier to read:
A true ternary operator only exists for arithmetic expressions:
((result = condition ? value_if_true : value_if_false))
For strings there only exist workarounds, like e.g.:
result=$([ "$a" == "$b" ] && echo "value_if_true" || echo "value_if_false")
(where "$a" == "$b" can be any condition test, respective [, can evaluate.)
Upvotes: 5
Reputation: 319
you can use this simple expression :
resVar=$([ numVar == numVal ] && echo "Yop" || echo "Nop")
Upvotes: 0