# Shell Boolean operations

May 23, 2021 Shell - An example of programming

## Objective

Last week introduced the numerical operation of the Shell programming paradigm, gave a brief introduction to the basic numerical calculation methods under the Shell, and this week we will discuss boolean operations, that is, how to manipulate "true and false values".

In Bash there are such constants (actually two built-in commands, which we'll say later), true and false, one representing true and one representing false. In this section, in addition to discussing these basic logical operations, we will discuss conditional testing and command lists in Shell programming and describe their relationship to Boolean operations.

## Regular Boolean operations

Here is a general introduction to the logical operations of the header in ``` Bash ``` with, or, and not.

### How to perform logical operations under the shell

#### Example: true or false

Test true and ``` true ``` ``` false ``` see ``` true ``` is true and ``` false ``` is false

``````\$ if true;then echo "YES"; else echo "NO"; fi
YES
\$ if false;then echo "YES"; else echo "NO"; fi
NO``````

#### Example: With operations

``````\$ if true && true;then echo "YES"; else echo "NO"; fi
YES
\$ if true && false;then echo "YES"; else echo "NO"; fi
NO
\$ if false && false;then echo "YES"; else echo "NO"; fi
NO
\$ if false && true;then echo "YES"; else echo "NO"; fi
NO``````

#### Example: or operation

``````\$ if true || true;then echo "YES"; else echo "NO"; fi
YES
\$ if true || false;then echo "YES"; else echo "NO"; fi
YES
\$ if false || true;then echo "YES"; else echo "NO"; fi
YES
\$ if false || false;then echo "YES"; else echo "NO"; fi
NO``````

#### Example: Non-operation, i.e. reverse

``````\$ if ! false;then echo "YES"; else echo "NO"; fi
YES
\$ if ! true;then echo "YES"; else echo "NO"; fi
NO``````

You ``` true ``` that true and ``` false ``` follow our understanding of logical operations, but in order to better understand shell implementations of logical operations, we have to figure ``` true ``` does true and ``` false ``` work?

### Is true and false in Bash what we usually think of as 1 and 0?

#### Example: Returns the value v.s. logical value

``` true ``` ``` false ``` not logical values in themselves, they are both built-in commands for the shell, but their return values are a "logical value":

``````\$ true
\$ echo \$?
0
\$ false
\$ echo \$?
1``````

You ``` true ``` that true returns 0 and ``` false ``` returns 1. The true values 1 and 0 we learned in discrete mathematics do not correspond, and the opposite is true.

#### Example: View true and false help and types

``````\$ help true false
true: true
Return a successful result.
false: false
Return an unsuccessful result.
\$ type true false
true is a shell builtin
false is a shell builtin``````

Description: ``` \$? ``` a special variable that holds the end state (exit status code) of the last process.

From the above, it's not hard to think of why it's important to ``` main ``` front of ``` int ``` 0 at the end in the C ``` return 0 ``` B ecause in the shell, 0 is used as a sign of the successful end of the program, which is the ``` true ``` and false in the ``` false ``` which reflect whether a program ended correctly, rather than the traditional true and false values (1 and 0), but instead returns 0 and 1. Fortunately, however, we do not have to care about these when we do logical calculations.

## Conditional testing

From the last section, we have a clear idea of what the "logical value" is under the shell: the return value when the process exits, true if it is successful, and false if it is not successfully returned.

Conditional testing uses ``` test ``` which is used for numerical testing (various numeric property tests), string testing (various string property tests), file testing (various file property tests), and we can do all kinds of routine work by determining whether the corresponding test is successful, plus the logical combination of various tests, we can do more complex work.

### Conditional testing is basically used

#### Example: Numerical testing

``````\$ if test 5 -eq 5;then echo "YES"; else echo "NO"; fi
YES
\$ if test 5 -ne 5;then echo "YES"; else echo "NO"; fi
NO``````

#### Example: String testing

``````\$ if test -n "not empty";then echo "YES"; else echo "NO"; fi
YES
\$ if test -z "not empty";then echo "YES"; else echo "NO"; fi
NO
\$ if test -z "";then echo "YES"; else echo "NO"; fi
YES
\$ if test -n "";then echo "YES"; else echo "NO"; fi
NO``````

#### Example: File testing

``````\$ if test -f /boot/System.map; then echo "YES"; else echo "NO"; fi
YES
\$ if test -d /boot/System.map; then echo "YES"; else echo "NO"; fi
NO``````

### A combination of various logical tests

#### Example: If a, b, and c are equal to the corresponding values below, print YES and pass -a for the "and" test

``````\$ a=5;b=4;c=6;
\$ if test \$a -eq 5 -a \$b -eq 4 -a \$c -eq 6; then echo "YES"; else echo "NO"; fi
YES``````

#### Example: Testing a "thing" is a file or directory, with -o for "or" operations

``````\$ if test -f /etc/profile -o -d /etc/profile;then echo "YES"; else echo "NO"; fi
YES``````

#### Example: Test whether something is a file, ``` ! ```

``````\$ if test ! -f /etc/profile; then echo "YES"; else echo "NO"; fi
NO``````

The above just demonstrates ``` test ``` simple tests of the test command, and you can ``` help test ``` usage of the test through ``` test ``` test. I t is important to ``` test ``` are some differences between the logical operations inside the test command and the logical operators of the shell, corresponding to ``` -a ``` and -amp;, ``` -o ``` and ``` && ``` ``` || ``` which cannot be confused. Not all operations ``` ! ```

### Compare -a with samp; samp;, -o with ||,! Test and test!

#### Example: Requires a file to be executable and content, implemented with -a and samp;

``````\$ cat > test.sh
#!/bin/bash
echo "test"
[CTRL+D]  # 按下组合键CTRL与D结束cat输入，后同，不再注明
\$ chmod +x test.sh
\$ if test -s test.sh -a -x test.sh; then echo "YES"; else echo "NO"; fi
YES
\$ if test -s test.sh && test -x test.sh; then echo "YES"; else echo "NO"; fi
YES``````

#### Example: Requires a string to be either empty or equal to a string

``````\$ str1="test"
\$ str2="test"
\$ if test -z "\$str2" -o "\$str2" == "\$str1"; then echo "YES"; else echo "NO"; fi
YES
\$ if test -z "\$str2" || test "\$str2" == "\$str1"; then echo "YES"; else echo "NO"; fi
YES``````

#### Example: Testing a number does not meet all of the specified criteria

``````\$ i=5
\$ if test ! \$i -lt 5 -a \$i -ne 6; then echo "YES"; else echo "NO"; fi
YES
\$ if ! test \$i -lt 5 -a \$i -eq 6; then echo "YES"; else echo "NO"; fi
YES``````

It's easy to ``` -a ``` and ``` -o ``` are used as parameters for the test command inside the test ``` || ``` while ``` && ``` and || are used to perform the return values of the test, ``` ! ``` both purposes. Concerns need to be paid to:

• Sometimes you can use ``` ! ``` ``` -eq ``` and ``` -ne ``` ``` -n ``` as opposed to testing whether two values are equal; ``` -z ```
• In ``` Bash ``` the ``` test ``` be replaced ``` 之后与 ``` with the operator, but it is important to note that additional spaces need to be added before
• When testing strings, it is recommended that all variables be included in double quotes to prevent only test parameters and no test content from appearing when the variable content is empty

Let's use examples to illustrate the three considerations above:

• ``` -ne ``` and ``` -eq ``` correspond, and we can sometimes get away ``` ! ```

``````\$ i=5
\$ if test \$i -eq 5; then echo "YES"; else echo "NO"; fi
YES
\$ if test \$i -ne 5; then echo "YES"; else echo "NO"; fi
NO
\$ if test ! \$i -eq 5; then echo "YES"; else echo "NO"; fi
NO``````
• Test ``` [ ] ``` ``` test ``` which will look a lot more "beautiful"

``````\$ if [ \$i -eq 5 ]; then echo "YES"; else echo "NO"; fi
YES
\$ if [ \$i -gt 4 ] && [ \$i -lt 6 ]; then echo "YES"; else echo "NO"; fi
YES``````
• Remember to add "" to ``` "" ``` ``` [ ``` remember to add ``` ] ``` more space before

``````\$ str=""
\$ if [ "\$str" = "test"]; then echo "YES"; else echo "NO"; fi
-bash: [: missing `]'
NO
\$ if [ \$str = "test" ]; then echo "YES"; else echo "NO"; fi
-bash: [: =: unary operator expected
NO
\$ if [ "\$str" = "test" ]; then echo "YES"; else echo "NO"; fi
NO``````

At this point, the conditional test is over, and here's a list of commands that we've actually used above, that is, a combination of multiple test ``` ! ``` through a sequence of commands combined by ``` || ``` ``` && ``` T his sequence of commands effectively ``` if/then ``` It's not hard to think of the following selection questions we often do in C-language programming (boring examples, but meaningful): ``` j ``` and what if so?

``````#include <stdio.h>
int main()
{
int i, j;

i=5;j=1;
if ((i==5) && (j=5))  printf("%d\n", j);

return 0;
}``````

It's easy to know that the ``` i==5 ``` will be printed, because the condition is true, and then there is the condition, to determine whether the whole condition is true, we have to make a later judgment, ``` j ``` 5, and then convert to the true ``` && ``` so the condition is true, print out 5. T herefore, this sentence can be interpreted ``` i ``` is equal to 5, ``` j ``` to 5, and if j ``` j ``` greater than 1 (because it was ``` j ``` then the value of j is printed. In this way, two if ``` && ``` are replaced with judgment ``` if ``` linked together.

It is based on the unique nature of logical computing ``` && ``` we can replace conditional branch structures such as ``` if/then ``` with ``` || ``` which results in a list of commands.

## The list of commands

### The law of execution of the command list

The execution law of the command list conforms to the operation law of the logical ``` && ``` and if the former is successfully returned, the subsequent command will be ``` || ``` and the command connected by ||, if the former is successfully returned, the subsequent command will not be executed, and the other is not.

#### Example: If the ping www.lzu.edu.cn, the connection information is printed

``\$ ping -c 1 www.lzu.edu.cn -W 1 && echo "=======connected======="``

The very interesting question comes up, which is what we mentioned above: Why should the C program return 0 at the end of the ``` main() ``` function? I f not, what happens when you put this program on the command list? Write your own simple C program and put it in the command list.

### The role of the command list

Sometimes replacing conditional branch ``` if/then ``` with command lists can save some code and make programs more beautiful and easy to read, such as:

#### Example: Judge the number of parameters of the program in the script, and the type of parameters

``````#!/bin/bash

echo \$#
echo \$1
if [ \$# -eq 1 ] && (echo \$1 | grep ^[0-9]*\$ >/dev/null);then
echo "YES"
fi``````

Description: The example above requires the number of parameters to be 1 and the type to be numeric.

Coupled ``` exit 1 ``` we'll save ``` if/then ``` structure

``````#!/bin/bash

echo \$#
echo \$1
! ([ \$# -eq 1 ] && (echo \$1 | grep ^[0-9]*\$ >/dev/null)) && exit 1

echo "YES"``````

After this processing, the judgment of program parameters requires only a simple line of code, and becomes more beautiful.

## Summary

This section describes the list of logical operations, conditional tests, and commands in Shell programming.