如何在bash中构建条件赋值?

Neu*_*ino 53 bash

我正在寻找一种在bash中构建条件赋值的方法:

在Java中它看起来像这样:

int variable= (condition) ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)

Dem*_*nex 62

如果您想要一种在shell脚本中定义默认值的方法,请使用以下代码:

: ${VAR:="default"}
Run Code Online (Sandbox Code Playgroud)

是的,该行以':'开头.我在shell脚本中使用它,所以我可以覆盖ENV中的变量,或使用默认值.

这是相关的,因为这是我对这种逻辑最常见的用例.]

  • 这是一种有价值的技术,但是':='表示法支持的唯一条件是"设置为"默认值"如果值未设置或为空".bash中直接支持问题中更一般的表示法. (3认同)
  • 在相等测试之前省略冒号只是为了取消设置的变量,如果它为null则不会更改它. (3认同)
  • 我完全同意,我给了它一个稍微偏离主题的免责声明. (2认同)

Ant*_*ney 53

根据乔纳森的评论:

variable=$(( 1 == 1 ? 1 : 0 ))  
Run Code Online (Sandbox Code Playgroud)

编辑:

我修改了原来的答案,它只是echo条件运算符的值,它实际上没有显示任何赋值.

  • 此外,应该注意,此运算符仅适用于Bash中的算术运算. (34认同)
  • 这对字符串不起作用:echo $((1 == 1?'hello':'world')) (17认同)
  • 如果我想设置的变量是一个字符串怎么办? (9认同)
  • 如果将开头的双括号一直向左移动,则可以完全自由地间隔(并放下美元符号).`((变量= 1 == 1?1:0))`或`((变量=(1 == 1)?1:0))`但可以说它在答案中给出的更具可读性. (3认同)

Kev*_*tle 27

myvar="default" && [[ <some_condition_is_true> ]]  && myvar="non-default"
Run Code Online (Sandbox Code Playgroud)

实例:

DELIM="" && [[ "$APP_ENV_RESOLVED" != "" ]] && DELIM=$INNER_DELIM
Run Code Online (Sandbox Code Playgroud)

条件可以是"((...))":

filepath=/proc/drbd && (( $# > 0 )) && filepath=$1
Run Code Online (Sandbox Code Playgroud)


Mar*_*egg 19

除了其他更一般的答案(特别是根据Jonathan的评论和Kevin的更一般的答案 [也支持字符串]),我想添加以下两个解决方案:


将变量设置为01基于条件:

(正如问题的例子所示.)

一般形式会读

(condition); variable=$?;
Run Code Online (Sandbox Code Playgroud)

其中$variable的结果是任一01condition可以是任何有效的条件表达式.

例如检查变量......

[[ $variableToCheck == "$othervariable, string or number to match" ]]
variable=$?
Run Code Online (Sandbox Code Playgroud)

...或检查文件的存在...

[ -f "$filepath" ]
fileExists=$?
Run Code Online (Sandbox Code Playgroud)

...或检查以下数字值$myNumber:

(( myNumber >= 1000000000 ))
is_huge_number=$?
Run Code Online (Sandbox Code Playgroud)


这种解决方案的优点是


请注意:在Bash中,特殊变量$?始终包含先前执行的语句的退出代码(或语句块; 有关详细信息,请参阅man bash).因此,阳性结果通常由值表示0,而不是1(请参阅下面的评论,感谢Assimilater 指出它).因此,如果条件为真(例如[[2 eq 2]])那么$?=0.

如果您在变量中需要0或1(例如,打印或进行数学计算),则需要使用前导感叹号(如下面的注释中GypsySpellweaver所指出的)使用布尔否定:( ! condition ); variable=$?! ( condition ); variable=$?.(但是,就发生的事情而言,可读性可能不太明显.)

Jonathan的另一个可能的解决方案variable=$(( 1 == 1 ? 1 : 0 ))- 然而,它正在创建一个子shell.

如果您想避免创建subhel,保持良好的可读性或具有任意条件,请使用以下解决方案之一.


将变量设置为任意值:

正如在大多数其他答案中所做的那样,它可以改编如下:

(condition) \
    && variable=true \
    || variable=false
Run Code Online (Sandbox Code Playgroud)

例如,如

[[ $variableToCheck == "$othervariable, string or number to match" ]] \
    && variable="$valueIfTrue" \
    || variable="$valueIfFalse"
Run Code Online (Sandbox Code Playgroud)

或者在正面检查中获得1,在失败时获得0(如问题示例中所示):

[[ $variableToCheck == "$othervariable, string or number to match" ]] \
    && variable=1 \
    || variable=0
Run Code Online (Sandbox Code Playgroud)

(对于最后一个例子, - 正如上面的注释中已经提到的那样 - 使用带有感叹号的布尔否定可以实现相同的目的:

[[ ! $variableToCheck == "$othervariable, string or number to match" ]]
variable=$?
Run Code Online (Sandbox Code Playgroud)


这种解决方案的优点是

  • 它可能被认为比凯文的答案更具可读性,并且
    myvar="default" && [[ <some_condition_is_true> ]] && myvar="non-default"
  • $valueIfTrue有条件评估如果需要的话,
    这将关系中你会做一些事情的情况下
    • 有副作用,比如
      • variable=$((i++)), 要么
      • { variable=$1; shift; }
    • 高计算,如
      • variable=$(find / -type f -name ListOfFilesWithThisNameOnMySystem)
  • 有点比ghostdog74的答案
    (这不过是伟大的,如果你有多个条件!)
  • 不像皮埃尔的回答那样打开子壳
  • 如上:


Pie*_*oui 11

我想用字符串进行条件赋值,最后得到:

SOWHAT=$([ "$MYVALUE" = "value" ] && echo "YES" || echo "NO")
Run Code Online (Sandbox Code Playgroud)


gho*_*g74 6

使用外壳/开关的另一种方法

case "$variable" in
  condition) result=1 ;;
          *) result=0 ;;
esac
Run Code Online (Sandbox Code Playgroud)


Ale*_*ray 6

大起大落对@Demosthenex,尤其是@Dennis威廉姆森的最短和最简单的我见过的解决方案.将它留给bash,需要一堆括号来进行简单的三元赋值.啊,60年代!并将它们放在一个例子中......

echo $BASHRULES;             # not defined
                             # no output
: ${BASHRULES:="SCHOOL"}     # assign the variable
echo $BASHRULES              # check it
SCHOOL                       # correct answer
: ${BASHRULES="FOREVER?"}    # notice the slightly different syntax for the conditional assignment
echo $BASHRULES              # let's see what happened!
SCHOOL                       # unchanged! (it was already defined)
Run Code Online (Sandbox Code Playgroud)

我很久以前就写过了......这些天我可能会对像...这样的解决方案感到更兴奋

PLATFORM=iphonesimulator
OTHERSDK=iphone && [[ $PLATFORM=~os ]]      \
                &&     OTHERSDK+=simulator  \
                ||     OTHERSDK+=os
Run Code Online (Sandbox Code Playgroud)

$OTHERSDKiphoneos

  • 谢谢你,@alex先生灰色.这是一个优秀的句法箭头,每个人都应该在他们的"bash"箭袋中...对于在这里发现它的好奇和/或不冒险的人来说,这种条件赋值也适用于`export`语句 - 你把它放在冒号前缀和美元符号语句-y部分,例如`:export $ {YO_DOGG:="global environment default"}` (2认同)

gri*_*ure 5

如果您想分配一个值,除非变量为空,请使用以下命令:

[ -z "$variable" ] && variable="defaultValue"
Run Code Online (Sandbox Code Playgroud)

你也可以把对方的条件放在 []

  • 变量扩展是为了处理这个,如下`: ${variable:='defaultValue'}` (3认同)