为什么:
#!/bin/bash
wtf=false
if [ $wtf ] || [ ! -f filethatexists.whatever ]
then
echo "WTF1"
fi
if [ ! -f filethatexists.whatever ]
then
echo "WTF2"
fi
打印:
WTF1
而不是什么?特别令人困惑的是,第二种形式按预期工作,第一种形式没有。
答案 0 :(得分:10)
基本测试
[ $wtf ]
测试中间的字符串是否为空。
由于$wtf
包含字符串'false'
,因此测试返回true,或退出状态0表示成功,因为'false'
与空字符串''
不同 - 因此你得到WTF1
作为回应。
尝试:
wtf=''
正如Gordon Davisson(和Dennis Williamson)所指出的,小心你正在测试的字符串是个好主意。实际上,我应该说我总是会使用[ -n "$wtf" ]
或[ -z "$wtf" ]
来测试变量是否已设置,因为在我学习shell时,这是必要的,就在四分之一世纪之前。我有来自Bash afficionados的反故事,你不必在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 ]
在此形式中,执行变量的内容,返回值确定测试是通过还是失败。碰巧true
和false
是返回适当值的Bash内置函数。
答案 2 :(得分:0)
if [ $wtf = true ] || [ ! -f . .