在bash脚本中,在“ if”语句中使用条件“或”


127

这个问题是我先前提出的问题的后遗症。该站点上的用户好心地帮助我确定了如何编写一个for遍历字符串值的bash 循环。例如,假设循环控制变量fname遍历string "a.txt" "b.txt" "c.txt"。我想echo“是!” when fname具有值"a.txt"or "c.txt",并且为echo“ no!” 除此以外。我已经尝试了以下bash shell脚本:

#!/bin/bash

for fname in "a.txt" "b.txt" "c.txt"
do
 echo $fname
 if [ "$fname" = "a.txt" ] | [ "$fname" = "c.txt" ]; then
 echo "yes!"
else
 echo "no!"
fi
done

我得到的输出:

a.txt

没有!

b.txt

没有!

c.txt

是!

为什么iffname有值时语句显然产生true "a.txt"?我使用|不正确吗?


3
在bash中,“或”运算符为“ ||” (C风格)。
Marius Cotofana 2012年

3
您也可以-o在同一个内使用[ ]
2012年

6
@Thor我宁愿||和分离[ ]-o简单的便携性,因为[不能保证支持超过4个参数。当然,如果目标语言是bash,则[无论如何都不会使用,因为bashs [[在许多方面都比较优越。
2012年

2
@ jw013谢谢。这是否意味着我应该使用if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]]而不是if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]
安德鲁(Andrew)

5
@Andrew是正确的,如果您已经像在声明shebang为bash那样。[[它的优点之一是它不进行单词拆分(特殊情况),因此[[ $unquoted_var = string ]]很安全。
2012年

Answers:


225

如果要说,请OR使用双管道(||)。

if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]

(使用的原始OP代码|只是将左侧的输出通过管道传递到右侧,就像任何普通管道一样。)


4
此外,||不执行标准逻辑“或”-会短路,并且仅在第一个命令失败时才运行第二个命令。
holdenweb

13
@holdenweb我敢肯定,大多数现代优化语言的工作方式都是相同的。OR如果第一个条件为真,则无需花费CPU周期来评估第二个条件。
bahamat

1
我以为bash很喜欢,==但是看到这个答案后,我决定去找它。显然,“它可以使用,但不是标准的”。我想如果您好奇的话,会把这个放在这里给别人看:stackoverflow.com/a/2237103
harperville 18/09/17

这也是test手册页建议的内容
cdosborn,

2
您也可以使用双括号测试- if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]](如果您需要或需要与关联的额外功能[[ ]])。
HankCa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.