Sujay U N
Sujay U N

Reputation: 5350

Shell Scripting Ternary operator to get string result

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

Answers (4)

Mac
Mac

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

ghoti
ghoti

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

Arkadiusz Drabczyk
Arkadiusz Drabczyk

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

melbx
melbx

Reputation: 319

you can use this simple expression :

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

Upvotes: 0

Related Questions