bash if with or and 否定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3800158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:41:27  来源:igfitidea点击:

bash if with or and negation

bash

提问by i30817

why does:

为什么:

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

print:

打印:

WTF1

WTF1

instead of nothing? It is especially perplexing that the second form works as expected and the first not.

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

采纳答案by Jonathan Leffler

The basic test

基本测试

[ $wtf ]

tests whether the string in the middle is empty or not.

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

Since $wtfcontains the string 'false', the test returns true, or exit status 0 for success, because 'false'is not the same as the empty string ''— and hence you get WTF1as the response.

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

Try with:

尝试:

wtf=''


As pointed out by Gordon Davisson(and Dennis Williamson), it is a good idea to be careful with strings that you are testing. Indeed, I should have stated that I would always use [ -n "$wtf" ]or [ -z "$wtf" ]to test whether a variable is set, because that was necessary when I was learning shell, once upon a quarter century ago. I've had counter stories from Bash afficionados that you don't have to worry about it in Bash - however, I think the code here provides a counter-example that in fact you do still have to worry about it.

正如戈登戴维森(和丹尼斯威廉姆森)所指出的,小心对待您正在测试的字符串是个好主意。事实上,我应该声明我总是使用[ -n "$wtf" ][ -z "$wtf" ]测试变量是否被设置,因为这在我学习 shell 时是必要的,曾经在 25 年前。我听过 Bash 爱好者的反例,你不必在 Bash 中担心它 - 但是,我认为这里的代码提供了一个反例,实际上你仍然需要担心它。

So, some best practices:

所以,一些最佳实践:

  • Enclose tested variables in double quotes, or
  • (In Bash), use [[ $wtf ]]which does know how to handle the variable expansion.
  • Use the -nor -ztests to test for non-empty or empty values.
  • 用双引号将测试的变量括起来,或
  • (在 Bash 中),使用[[ $wtf ]]which 知道如何处理变量扩展。
  • 使用-n-z测试来测试非空或空值。

There can be exceptions to the rules - but you will not go far wrong following them.

规则可能有例外 - 但遵循它们不会出错。

Consider the code:

考虑代码:

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"

That produces:

这产生:

WTF1
WTF2
WTF3
WTF6
WTF7

with both bash and ksh (as found on MacOS X 10.6.4, when run with 'bash testcode.sh' or 'ksh testcode.sh'). A real Bourne shell (if you can still find such a thing) would object to the double-bracket operations - it would not be able to find the command '[[' on $PATH.

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

You can extend the testing to cover more cases ad nauseam.

您可以扩展测试以涵盖更多令人作呕的情况。

回答by Paused until further notice.

Here's a handy little trick:

这是一个方便的小技巧:

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

In this form, the contents of the variable are executed and the return value determines whether the test passes or fails. It happens that trueand falseare Bash builtins that return the appropriate value.

在这种形式中,变量的内容被执行,返回值决定了测试是通过还是失败。碰巧的是,true并且false是返回适当值的 Bash 内置函数。

回答by beta0x64

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

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