Linux if true false

bash «if [ false ];» returns true instead of false — why?

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.

BTW, a script starting with #!/bin/sh is not a bash script — it’s a POSIX sh script. Even if the POSIX sh interpreter on your system is provided by bash, it turns off a bunch of extensions. If you’re wanting to write bash scripts, use #!/bin/bash or its locally-appropriate equivalent ( #!/usr/bin/env bash to use the first bash interpreter in the PATH).

6 Answers 6

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

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

bash has no Boolean data type, and so no keywords representing true and false. The if statement merely checks if the command you give it succeeds or fails. The test command takes an expression and succeeds if the expression is true; a non-empty string is an expression that evaluates as true, just as in most other programming languages. false is a command which always fails. (By analogy, true is a command that always succeeds.)

if [[ false ]]; returns true, too. As does if [[ 0 ]]; . And if [[ /usr/bin/false ]]; does not skip the block, either. How can false or 0 evaluate to non-zero? Damn this is frustrating. If it matters, OS X 10.8; Bash 3.

Don’t mistake false for a Boolean constant or 0 for an integer literal; both are just ordinary strings. [[ x ]] is equivalent to [[ -n x ]] for any string x that doesn’t start with a hyphen. bash doesn’t have any Boolean constants in any context. Strings that look like integers are treated as such inside (( . )) or with operators such as -eq or -lt inside [[ . ]] .

A Quick Boolean Primer for Bash

The if statement 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).

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

The true and false statements 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:

if [ foo ]; then . # "if the string 'foo' is non-empty, return true" if foo; then . # "if the command foo succeeds, return true" 
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» .

Читайте также:  Linux ubuntu установка deb

When using the test statement, 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 test something as pass/fail (aka «true»/»false»), then pass a command to your if or && etc. statement, without brackets. For complex comparisons, use brackets with the proper operators.

And yes, I’m aware there’s no such thing as a native boolean type in Bash, and that if and [ and true are technically «commands» and not «statements»; this is just a very basic, functional explanation.

Источник

values of true and false in shell

I read that in shell, true command returns 0 => logical true. false command return 1 => logical false. But I get surprising results when i run.

if [ 0 ] then echo "0 is true." else echo "0 is false." fi if [ 1 ] then echo "1 is true." else echo "1 is false." fi if [ false ] then echo "false is true." else echo "false is false." fi if [ true ] then echo "true is true." else echo "true is false." fi 

doesn’t this if [ 1 ] mean if 1 exist or if 1 is not null I mean I am neither a unix nor a shell guy but I am curious? if(1) It is like that in C,C# and Java as much as I know.

2 Answers 2

The test if [ 0 ] tests whether 0 is the empty string (it isn’t) and returns true if it is not empty. The test if [ 1 ] similarly tests whether 1 is the empty string and returns true if it is not empty. Likewise, the other two tests check whether the strings true and false are empty.

If you want to test the commands, execute the commands:

if false; then echo False is true; else echo False is false; fi if true ; then echo True is true; else echo True is false; fi 

Most machines don’t have commands called 0 or 1 , so you can’t readily invoke them as commands.

You could also experiment with:

if sh -c "exit 1"; then echo Shell exited as true; else echo Shell exited as false; fi if sh -c "exit 0"; then echo Shell exited as true; else echo Shell exited as false; fi 

In 7th Edition Unix, /bin/test (or possibly /usr/bin/test ) was the test program, but you would normally find a link /bin/[ . When it was invoked by the name [ , it demanded that its last argument was ] , so you could write a square bracketed condition. (Macs with macOS 10.14.6 Mojave still have /bin/[ — it still works. Linux systems usually have /usr/bin/[ , and it still works too.)

Shortly after that, the test operation was built into the shell, instead of being a separate executable, but the semantics remained largely unchanged. Because they are now different (built-in vs the executable), sometimes the test operations have different functionality. POSIX defines a baseline; various shells and systems provide various extensions.

Читайте также:  Serial port testing linux

To this day, the autoconf suite recommends the use of test over [ , though that is primarily because it uses square brackets for another purpose.

Источник

Check if a condition is false

It is seems to be an easy question, I wonder why googling didn’t give anything helpful — nor in StackOverflow, nor in tutorials. I just need to check using bash that a condition is false. Of what I found I tried

if ! [ 0==2 ]; then echo Hello; fi 
if [ ! 0==2 ]; then echo Hello; fi 

none of them print Hello. I found only two similar questions, but the end answer in both cases was restructured code to not use the «false» condition.

@JoachimPileborg the test is a whole separate command. What the difference between the test and if , such, that I should use the test instead?

If you check the linked manual page, you will see that [ is an alias for the test command. In fact, the if command just checks the result of another command, in this case the test command. It might all be handled internally by the shells these days, but you should see if as just a normal command, which in turn calls another command.

I disagree with Joachim’s suggestion to view if as a command. if is a keyword in the grammar of the shell which introduces a conditional clause. It is emphatically not a command. At some point, someone thought it would be a good idea to introduce the command [ so that if [ . would appear to be two grammatical symbols in the shell, but [ is not part of the shell grammar.

4 Answers 4

if ! [ 0 == 2 ]; then echo Hello; fi 

You lacked space around the equality operator.

This might be the time to read http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html — especially the sections about if then else and operators. I usually have this open when I am writing scripts..

Yes, that work! Please, can you add a little explanation to the answer, why the ! in my case didn’t work? I.e. this command if [ 0==0 ]; then echo Hello; fi workd fine, so what the reason?

@YagamyLight Probably because the test operator [ . ] check for an expression. The 0==0 is not an operation but an expression. Try to do [ gfhjg ]; echo $? and it will answer with 0 (-> true) as if you write [ 1 == 1 ]; echo $? , meanwhile if you write [ 1 == 2 ]; echo $? it will answer 1 (-> false)

@WilliamPursell If you want your users to have the flexibility to use a better, smaller, faster shell — this is a bash-specific question. I normally stick #!/bin/bash she-bang because I don’t test my scripts with any other shells. Of course, in autoconf world your comment would make sense.

@WilliamPursell Because ignorance is bliss and portability by adhering to stone-age tools is expensive. I suggest you complain to bash developers to remove non-POSIX shell extensions. And to developers of better shells.

For mathematical evaluations use (( )) in bash. For text use [[ ]] .

if (( $i == 0 )); then echo "i is 0" else echo "i is unequal 0" 

In addition to bash’s mathematical evaluations, you can use boolean expressions instead of if :

[max@localhost:~] $ (( 0 == 0 )) && echo True || echo False True [max@localhost:~] $ (( 0 != 0 )) && echo True || echo False False 

If you are using the test command ( [..] ) you can use the comparison option for integer: -eq , equal, and -ne , not equal.

if [ 0 -eq 2 ]; then echo true ; else echo false ; fi # false if [ 0 -eq 0 ]; then echo true ; else echo false ; fi # true if [ 0 -ne 2 ]; then echo true ; else echo false ; fi # true if [ 0 -ne 0 ]; then echo true ; else echo false ; fi # false 

In bash the operator [. ] is the equivalent of test , a command that checks file types and compare values; test is an internal command: if you ask to your shell with type [ it will answer [ is a built in shell command . You can find the binary too usually in /usr/bin/[ .

Читайте также:  Dts linux что это

The SYNOPSIS is test EXPRESSION , as you can read from man test or from info coreutils test invocation .

An omitted EXPRESSION defaults to false. Otherwise, EXPRESSION is true or false and sets exit status.

This is an excerpt from man that cam help to understand a little better

  • ( EXPRESSION ) EXPRESSION is true. So it’s easy to incur in the error to consider as an operation 0==1 . (The operation is 0 == 1 with spaces, 0==1 is an expression).
  • ! EXPRESSION EXPRESSION is false.
  • .
  • INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2
  • INTEGER1 -ne INTEGER2 INTEGER1 is NOT equal to INTEGER2

From info coreutils test invocation you can read about the exit status of test.

 0 if the expression is true, 1 if the expression is false, 2 if an error occurred. 

Источник

How does the keyword “if” test if a value is true or false?

Output: No But echo «$word» | grep -q «$letter» will return 1, so why is the result is No . How does the keyword if test the value returned by the command after if ?

3 Answers 3

The return value of a command is checked. [ 1 ] has a return value of 0 (true). Any other return value (like 1 ) indicates an error.

You can display the return value of the last executed command using the $? variable:

true echo $? # returned 0 false echo $? # returned 1 echo $? # returned 0 as the last executed command is 'echo', and not 'false' 

It looks like 0 is an expression which evaluates to true . [ 0 = 1 ] has a return value of 1 (expected value) and [ 0 = 0 ] has a return value of 0 . Run man test for more information about test (a.k.a. [ )

[ 1 ] or [ 0 ] evaluates to true because test / [ with single parameter simply checks whether the parameter string (here 1 or 0 ) is non-empty. iow [ «» ] would be false.

In unix land, 0 is true and 1 is false.

if [ 1 ] then echo "Yes" else echo "No" fi 

«If» checks the exit code of the given command for true/false (i.e. zero/non-zero).

The square brackets actually invoke the «test» command (see «man test» for more information) and give the exit code to if.

«test 1» (or indeed «test any_string») returns true (0) so «Yes» is output.

For your second example, this outputs «No» because «nuxi» isn’t found in «Linux», if you change «nuxi» to «nux» (perhaps this was a typo?) and remove the spaces around the = then you will get the behaviour you expect. e.g.

word=Linux letter=nux if echo "$word" | grep -q "$letter" then echo "Yes" else echo "No" fi 

Источник

Оцените статью
Adblock
detector