Bash if [假] ; 返回真

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19670061/
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-10 00:22:27  来源:igfitidea点击:

Bash if [ false ] ; returns true

bashconditional-operator

提问by tenmiles

Been learning bash this week and ran into a snag.

本周一直在学习 bash 并遇到了障碍。

#!/bin/sh

if [ false ]; then
    echo "True"
else
    echo "False"
fi

This will always output True even though the condition would seem to indicate otherwise. If I remove the brackets []then it works, but I do not understand why.

即使条件似乎另有指示,这也将始终输出 True。如果我删除括号[]然后它工作,但我不明白为什么。

回答by chepner

You are running the [(aka test) command with the argument "false", not running the command false. Since "false" is a non-empty string, the testcommand always succeeds. To actually run the command, drop the [command.

您正在使用参数“false”运行[(又名test)命令,而不是运行命令false。由于“false”是一个非空字符串,所以test命令总是成功的。要实际运行该命令,请删除该[命令。

if false; then
   echo "True"
else
   echo "False"
fi

回答by Beejor

A Quick Boolean Primer for Bash

Bash 的快速布尔入门

The ifstatement takes a command as an argument(as do &&, ||, etc.). The integer result code of the command is interpreted as a boolean (0/null=true, 1/else=false).

if声明需要一个命令作为参数(如做&&||等)。命令的整数结果代码被解释为布尔值(0/null=true,1/else=false)。

The teststatement takes operators and operands as argumentsand returns a result code in the same format as if. An alias of the teststatement is [, which is often used with ifto perform more complex comparisons.

test语句将运算符和操作数作为参数,并以与if. test语句的别名是[,通常用于if执行更复杂的比较。

The trueand falsestatements do nothing and return a result code(0 and 1, respectively). So they can be used as boolean literals in Bash. But if you put the statements in a place where they're interpreted as strings, you'll run into issues. In your case:

truefalse语句什么也不做,返回的结果代码(0和1,分别)。所以它们可以在 Bash 中用作布尔文字。但是,如果将语句放在将它们解释为字符串的位置,则会遇到问题。在你的情况下:

if [ foo ]; then ... # "if the string 'foo' is non-empty, return true"
if foo; then ...     # "if the command foo succeeds, return true"

So:

所以:

if [ true  ] ; then echo "This text will always appear." ; fi;
if [ false ] ; then echo "This text will always appear." ; fi;
if true      ; then echo "This text will always appear." ; fi;
if false     ; then echo "This text will never appear."  ; fi;

This is similar to doing something like echo '$foo'vs. echo "$foo".

这类似于做类似echo '$foo'vs. 的事情echo "$foo"

When using the teststatement, the result depends on the operators used.

使用test语句时,结果取决于所使用的运算符。

if [ "$foo" = "$bar" ]   # true if the string values of $foo and $bar are equal
if [ "$foo" -eq "$bar" ] # true if the integer values of $foo and $bar are equal
if [ -f "$foo" ]         # true if $foo is a file that exists (by path)
if [ "$foo" ]            # true if $foo evaluates to a non-empty string
if foo                   # true if foo, as a command/subroutine,
                         # evaluates to true/success (returns 0 or null)

In short, if you just want to test something as pass/fail (aka "true"/"false"), then pass a command to your ifor &&etc. statement, without brackets. For complex comparisons, use brackets with the proper operators.

简而言之,如果您只想测试通过/失败(又名“真”/“假”),则将命令传递给您的if&&等语句,不带括号。对于复杂的比较,请使用带有正确运算符的括号。

And yes, I'm aware there's no such thing as a native boolean type in Bash, and that ifand [and trueare technically "commands" and not "statements"; this is just a very basic, functional explanation.

是的,我知道在 Bash 中没有本地布尔类型这样的东西,而且ifand[和 andtrue技术上是“命令”而不是“语句”;这只是一个非常基本的功能性解释。

回答by Rodrigo

I found that I can do some basic logic by running something like:

我发现我可以通过运行类似的东西来做一些基本的逻辑:

A=true
B=true
if ($A && $B); then
    C=true
else
    C=false
fi
echo $C

回答by psh

Using true/false removes some bracket clutter...

使用 true/false 消除了一些括号混乱...

#! /bin/bash    
#  true_or_false.bash

[ "$(basename ##代码##)" == "bash" ] && sourced=true || sourced=false

$sourced && echo "SOURCED"
$sourced || echo "CALLED"

# Just an alternate way:
! $sourced  &&  echo "CALLED " ||  echo "SOURCED"

$sourced && return || exit