Bash if [false]; returns true

I studied bash this week and ran into a problem.

#!/bin/sh if [ false ]; then echo "True" else echo "False" fi 

This will always output True, even if the condition appears to indicate otherwise. If I remove the brackets [] then it will work, but I don't understand why.

+67
bash
Oct 29 '13 at 22:04
source share
4 answers

You execute the [ (aka test ) command with the "false" argument, and not the false command. Since false is a non-empty string, the test command always succeeds. To execute the command, release the command [ .

 if false; then echo "True" else echo "False" fi 
+86
Oct 29 '13 at 22:06
source share

I found that I can do the basic logic by doing something like:

 A=true B=true if ($A && $B); then C=true else C=false fi echo $C 
+1
Jan 24 '17 at 6:41
source share

Using true / false removes some messy mess ...

 #! /bin/bash # true_or_false.bash [ "$(basename $0)" == "bash" ] && sourced=true || sourced=false $sourced && echo "SOURCED" $sourced || echo "CALLED" # Just an alternate way: ! $sourced && echo "CALLED " || echo "SOURCED" $sourced && return || exit 
0
Nov 07 '17 at 13:00
source share

Fast Boolean Primer for Bash

The if takes the command as an argument (like && , || , etc.). Integer the resulting command code is interpreted as logical (0 / null = true, 1 / else = false).

The test statement takes operators and operands as arguments and returns the result code in the same format as if . The alias for the test statement is [ , which is often used with if to do more complex comparisons.

The true and false operators do nothing and return the result code (0 and 1, respectively). Therefore, they can be used as Boolean literals in Bash. But if you put statements in a place where they are interpreted as strings, you will run into problems. In your case:

 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 like doing something like echo '$foo' vs. echo "$foo" .

When using the test operator, the result depends on the operators used.

 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 check something like pass / fail (aka "true" / "false"), then pass the command to your if or && , etc. without brackets. For complex comparisons, use parentheses with the appropriate operators.

And yes, I know that in Bash there is no such thing as a native Boolean type, and that if and [ and true are technically "commands", not "statements"; this is just a basic, functional explanation.

0
Dec 18 '17 at 20:58
source share



All Articles