bash如果有或否定

i30*_*817 12 bash

为什么:

#!/bin/bash
wtf=false
if [ $wtf ] || [ ! -f filethatexists.whatever ]
then
 echo "WTF1"
fi
if [ ! -f filethatexists.whatever ]
then
 echo "WTF2"
fi
Run Code Online (Sandbox Code Playgroud)

打印:

WTF1

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

Jon*_*ler 10

基本测试

[ $wtf ]
Run Code Online (Sandbox Code Playgroud)

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

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

试试:

wtf=''
Run Code Online (Sandbox Code Playgroud)

正如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"
Run Code Online (Sandbox Code Playgroud)

这产生:

WTF1
WTF2
WTF3
WTF6
WTF7
Run Code Online (Sandbox Code Playgroud)

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

您可以扩展测试以涵盖更多令人作呕的案例.