Shell 脚本化三元运算符以获取字符串结果

Shell Scripting Ternary operator to get string result

在 shell 脚本中,我使用这样的三元运算符:

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

我观看了 Derek Banas 的 shell 脚本教程,并在视频的 41:00 获得了上述语法

https://www.youtube.com/watch?v=hwrnmQumtPw&t=73s

当我们将数字分配给 resVar 时,上面的代码有效,但是如果我尝试将字符串分配给 resVar,它总是 returns 0.

(( numVar == numVal ? (resVar="Yop") : (resVar="Nop") ))

也尝试过

resVar=$(( numVar == numVal ? (echo "Yop") : (echo "Nop") ))

那么这样做的正确方法是什么?

您可以使用这个简单的表达式:

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

您没有告诉我们您使用什么 shell 但您可能使用 bash 或类似的东西。 Bash 中的三元运算符仅适用于数字 在 ARITHMETIC EVALUATION 部分下的 man bash 中解释:

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

以及当您使用 "Yop"resVar 时分配 0 的原因 "Nop" 是因为这样的字符串在 bash 中不是有效数字并且 因此它的计算结果为 0man bash 中也有说明 同款:

A null value evaluates to 0.

这个维基百科中也有解释 article 如果你找到了 更容易阅读:

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.)

A​​rkadiusz 已经指出三元运算符是 bash 中的一个算术特征,在字符串中不可用。如果你想在字符串中使用这种功能,你总是可以使用数组:

$ 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

当然,如果您只是处理数组中位于 01 位置的两个值,则不需要三元组;以下实现了同样的事情:

$ resvar="${arr[$((numVar==numVal))]}"