该怎么测试多个特性?必须嵌套 if 语句吗?
解决方案
使用 -a(逻辑与)和 -o(逻辑或)运算符将多个测试条件组合成一个表达式。例如:
if [ -r $FILE -a -w $FILE ]
该 if 语句会测试指定文件是否可读且可写。
讨论
因为所有的文件测试条件都隐含了该文件存在的测试,所以测试文件可读性时不用测试文件是否存在。如果文件不存在,自然也就不可读。
这些逻辑运算符(-a 表示 AND,-o 表示 OR)可用于所有的测试条件,并不局限于文件测试。
同一个语句中可以出现多个 AND/OR。你可能要用括号来获得正确的优先级,比如 a and (b or c),但一定要记得在括号前加上反斜杠或将括号放进引号,以消除其特殊含义。不过,可别让整个表达式都出现在引号中,这会令其作为整体被当成是对空字符串的测试。以下这个测试更为复杂,其中的括号已经过正确转义。
if [ -r "$FN" -a \( -f "$FN" -o -p "$FN" \) ]
不要认为这些子表达式的求值顺序和 Java 或 C 中的顺序一样。在后两种语言中,如果 AND 表达式的第一部分为假(或者 OR 表达式的第一部分为真),则不会再对第二部分求值(我们称之为表达式短路)。但是,因为 shell 会在准备对表达式求值时对语句进行好几趟处理(如执行参数替换等),所以由逻辑运算符连接在一起的两部分可能会被部分求值。尽管在这个简单示例中不会有什么问题,但碰上更复杂的情况,那可就未必了。例如:
if [ -z "$V1" -o -z "${V2:=YIKES}" ]
如果 $V1
为空,那就完全不用再对 if 语句中的第二个条件(检查 $V2
是否为空)求值了,但 $V2
的值也许已经被修改了(对 $V2
进行变量替换的副作用)。变量替换发生在 -z 测试之前。是不是被搞晕了?别去依赖条件表达式短路就行了。如果的确需要这种行为,可以将 if 语句拆成两个嵌套 if 语句,或者使用 &&
和 ||
。
酷客网相关文章:
评论前必须登录!
注册