bash如果有或否定

时间:2010-09-26 22:53:24

标签: bash

为什么:

#!/bin/bash
wtf=false
if [ $wtf ] || [ ! -f filethatexists.whatever ]
then
 echo "WTF1"
fi
if [ ! -f filethatexists.whatever ]
then
 echo "WTF2"
fi

打印:

WTF1

而不是什么?特别令人困惑的是,第二种形式按预期工作,第一种形式没有。

3 个答案:

答案 0 :(得分:10)

基本测试

[ $wtf ]

测试中间的字符串是否为空。

由于$wtf包含字符串'false',因此测试返回true,或退出状态0表示成功,因为'false'与空字符串''不同 - 因此你得到WTF1作为回应。

尝试:

wtf=''

正如Gordon Davisson(和Dennis Williamson)所指出的,小心你正在测试的字符串是个好主意。实际上,我应该说我总是会使用[ -n "$wtf" ][ -z "$wtf" ]来测试变量是否已设置,因为在我学习shell时,这是必要的,就在四分之一世纪之前。我有来自Bash afficionados的反故事,你不必在Bash中担心它 - 但是,我认为这里的代码提供了一个反例,事实上你仍然需要担心它。

所以,一些最佳实践:

  • 用双引号括起测试变量,或
  • (在Bash中),使用知道如何处理变量扩展的[[ $wtf ]]
  • 使用-n-z测试来测试非空值或空值。

规则可以有例外 - 但是跟随它们不会出错。

考虑代码:

wtf="1 -eq 0"
 [  $wtf  ]  && echo "WTF0"
[[  $wtf  ]] && echo "WTF1"
wtf="false"
 [  $wtf  ]  && echo "WTF2"
[[  $wtf  ]] && echo "WTF3"
wtf=""
 [  $wtf  ]  && echo "WTF4"
[[  $wtf  ]] && echo "WTF5"
wtf="false"
 [ "$wtf" ]  && echo "WTF6"
[[ "$wtf" ]] && echo "WTF7"
wtf=""
 [ "$wtf" ]  && echo "WTF8"
[[ "$wtf" ]] && echo "WTF9"

产生:

WTF1
WTF2
WTF3
WTF6
WTF7

同时使用bash和ksh(在MacOS X 10.6.4上找到,使用'bash testcode.sh'或'ksh testcode.sh'运行时)。一个真正的Bourne shell(如果你仍然可以找到这样的东西)会反对双括号操作 - 它将无法在[[上找到命令“$PATH”。

您可以延长测试范围以覆盖更多令人作呕的案例。

答案 1 :(得分:4)

这是一个方便的小技巧:

wtf=false
if $wtf || [ ! -f filethatexists.whatever ]

在此形式中,执行变量的内容,返回值确定测试是通过还是失败。碰巧truefalse是返回适当值的Bash内置函数。

答案 2 :(得分:0)

if [ $wtf = true ] || [ ! -f . .