bash-shell Advanced Programming--Operators and Related Topics

Operators and related topics

Operator

assignment

Assigning, initializing, or modifying the value of a variable

=

A general assignment operator that can be used for arithmetic and string assignments.

var=12
car=bmw # Cannot have a blank character after the = sign

Don't confuse = assignment operator with = test operator

# =Here is the test operator
if [ "$string1" = "$string2" ]
# If ["X$string1" = "X$string2"] is a safer practice,
# This prevents errors when one of the two variables is empty.
# (The character "X" as a prefix can cancel each other on either side of the equation.)
then
	command
fi

arithmetic operator
+
Addition calculation

-
Subtraction calculation

*
Multiplication calculation

/
Division calculation

**

exponentiation

 # In Bash, version 2.02, the'**'power operator was introduced.
 
let "z=5**3"
echo "z = $z"
# z = 125

%

Modular operation, or complementary operation

greatest common factor

#!/bin/bash
# gcd.sh: Maximum common divisor
#Algorithms using Euclid

# The "greatest common divisor" (gcd) of two integers,
#+is the maximum number that two integers can divide at the same time.

# The Euclid algorithm uses continuous division.
# In each cycle,
#+Divided<--Divided
#+Division<--Remainder
#+until the remainder= 0.
#+In the last loop, gcd = dividend.
#
# A better discussion of the Euclid algorithm can be found at
#+ Jim Loy's site, http://www.jimloy.com/number/euclids.htm.

# ------------------------------------------------------
# Parameter Check
ARGS=2
E_BADARGS=65

if [ $# -ne "$ARGS" ]
then
 echo "Usage: `basename $0` first-number second-number"
 exit $E_BADARGS
fi
# ------------------------------------------------------

gcd ()
{
 dividend=$1
# Assignment at will.
 divisor=$2
#+Here, it doesn't matter which value is given.
# Why is that okay?
 remainder=1
# If an uninitialized variable is used in the loop,
#+Then in the first loop,
#+It will produce an error message.
 until [ "$remainder" -eq 0 ]
 do
let "remainder = $dividend % $divisor"
dividend=$divisor
# Now repeat with the two smallest numbers.
divisor=$remainder
 done
# Algorithms for Euclid
}
# Last $dividend is the gcd.
gcd $1 $2
echo; echo "GCD of $1 and $2 = $dividend"; echo
# Exercise :
# --------
# Check the command line parameters passed in to make sure they are all integers.
#+If it's not an integer, give an appropriate error message and exit the script.
exit 0

results of enforcement

andrew@andrew:/work/bash/src$ bash gcd.sh  2345 56

GCD of 2345 and 56 = 7

+=
"Add-Equal" (add a constant to the value of the variable and assign the result to the variable) let "var += 5" The value of the VaR variable will be added 5 to the original value.

-=

"Minus-equal" (subtracts the value of a variable from a constant and assigns the result to the variable)

*=
Multiply-Equal (multiplies the value of a variable by a constant value, and assigns the result to a variable)
Let "var *= 4" The result of the VaR variable will be multiplied by 4.

/=
Divide-Equal (divides the value of a variable by a constant value, and assigns the result to the variable)

%=
Modulo-Equal (modulo a variable by dividing it by a constant and assigning the result to a variable)
Arithmetic operators often appear in expr or let expressions.

Using Arithmetic Operators

#!/bin/bash
# Use 10 different methods to count to 11.
n=1; echo -n "$n "

let "n = $n + 1"
# let "n = n + 1" also works.
echo -n "$n "

: $((n = $n + 1))
# ":" is necessary because if there is no ":", then
#+ Bash will try to interpret'$((n = $n + 1))'as a command.
echo -n "$n "

(( n = n + 1 ))
# The above sentence is a simpler way.
# Thank you, David Lombard, for pointing this out.
echo -n "$n "

n=$(($n + 1))
echo -n "$n "

: $[ n = $n + 1 ]
# ":" is necessary because if there is no ":", then
#+ Bash will try to interpret'$[n = $n + 1]'as a command.
# This sentence works even if "n" is initialized as a string.
echo -n "$n "
 
n=$[ $n + 1 ]
# This sentence works even if "n" is initialized as a string.
#*This type of structure should be avoided as much as possible because it is obsolete and not portable.
echo -n "$n "  # No final carriage return when echo output
# Now let's do a C-style incremental operation.
 
let "n++"
# Let'++ n'is also possible.
echo -n "$n "

(( n++ ))
# (++n) is also possible.
echo -n "$n "
 
: $(( n++ ))
# : $((++n)) is also possible.
echo -n "$n "

: $[ n++ ]
# : $[++n]] is also possible.
echo -n "$n "
echo
exit 0

results of enforcement

andrew@andrew:/work/bash/src$ bash algroth.sh 
1 2 3 4 5 6 7 8 9 10 11 

An integer variable in bash is actually a signed long(32-bit) integer value that ranges from -2147483648 to 2147483647.If you do arithmetic beyond this range, you will not get the results you expect.

You can't do floating-point calculations directly in bash. If you need floating-point calculations, you need to use bc in your script. This command can do floating-point calculations or call Mathematical Library functions.

Bitwise operators

<<

Move one bit to the left

<<=

"Move left-assign"
let "var <<= 2"
The result of this sentence is that the variable var is moved 2 bits to the left (that is, multiplied by 4)

>>

Move one bit to the right

>>=

Right Shift-Assignment

&
Bitwise and

&=
"Bitwise and-Assignment"

|
Bitwise or

|=
"Bitwise or-Assignment"

~
Bitwise Reverse

!

Bitwise Not

^
Bitwise XOR

^=
"Bitwise XOR-Assignment"

Logical Operator

&&
And (logical)

if [ $condition1 ] && [ $condition2 ]
# Same as if [$condition1-a $condition2]
# If both condition1 and condition2 are true, the result is true.

if [[ $condition1 && $condition2 ]] #It's fine too
## Note &&Symbols are not allowed in [...]

||
Or (logical)

if [ $condition1 ] || [ $condition2 ]
# Same as if [$condition1 -o $condition2]
# If one of condition1 or condition2 is true, the result is true.

if [[ $condition1 || $condition2 ]]
# It's fine too.
# Note that the || operator cannot appear in the [...] structure.

Mixed Conditional Test Using &&and||

#!/bin/bash
 
a=24
b=47

# The condition holds if a==24 and b==47
if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]
then
 echo "Test #1 succeeds."
else
 echo "Test #1 fails."
fi

# ERROR: Not in single brackets &&but in double brackets
if [ "$a" -eq 24 && "$b" -eq 47 ]
#+Try running'['$a'-eq 24'
#+Failed because no matching']'was found.
#
# Note: if [[$a-eq 24 & & & &$b-eq 24]] also works.
# if-test structure with double middle brackets is better than
#+Single middle bracket if-test structure is more flexible.
#(Line 17'&'has a different meaning from line 6'&'.)

if [ "$a" -eq 98 ] || [ "$b" -eq 47 ]
then
 echo "Test #2 succeeds."
else
 echo "Test #2 fails."
fi

# The -a and -o options are provided
#+An optional mixed-condition test method.

if [ "$a" -eq 24 -a "$b" -eq 47 ]
then
 echo "Test #3 succeeds."
else
 echo "Test #3 fails."
fi

if [ "$a" -eq 98 -o "$b" -eq 47 ]
then
 echo "Test #4 succeeds."
else
 echo "Test #4 fails."
fi

a=rhino
b=crocodile
if [ "$a" = rhino ] && [ "$b" = crocodile ]
then
 echo "Test #5 succeeds."
else
 echo "Test #5 fails."
fi

exit 0

Detecting the script using the shellcheck tool

andrew@andrew:/work/bash/src$ shellcheck if_else.sh 

In if_else.sh line 15:
if [ "$a" -eq 24 && "$b" -eq 47 ]
^-- SC1073: Couldn't parse this if expression.


In if_else.sh line 57:
exit 0
      ^-- SC1050: Expected 'then'.
      ^-- SC1072: Expected 'then'.. Fix any mentioned problems and try again.

Prompt the script for a problem on line 15. Look at line 15 of the script to see that

If ['$a'-eq 24 & & & &'$b'-eq 47] script uses &&quot in single brackets

The &&and || operators can also be used in arithmetic contexts.

andrew@andrew:~$ echo $(( 1 && 2 )) $((3 && 0)) $((4 || 0)) $((0 || 0))
1 0 1 0

,

, sign operator, comma operator can link two or more arithmetic operations, all operations will be run, but only the result of the last operation will be returned

let "t1 = ((5 + 3, 7 - 1, 15 - 4))"
echo "t1 = $t1"   # t1 = 11
let "t2 = ((a = 9, 15 / 3))" # Set "a" and calculate "t2".
echo "t2 = $t2 a = $a"# t2 = 5 a = 9

numeric constants

By default, shell scripts treat numbers as decimal, unless they are marked or prefixed with a special tag.If a number starts with 0, it is 8-digit; if a number starts with 0x, it is 16-digit; if # is embedded in the middle of the number, it is considered a BASE#NUMBER notation.

Numeric Constant Representation

#!/bin/bash
# Number.sh: Several different numeric representations.

# 10-digit: default
let "dec = 32"
echo "decimal number = $dec"
# 32
# It's nothing special.


# Octal: Begins with'0'(zero)
# Octal 32 happens to be 3*8 + 2 = 26
let "oct = 032"
echo "octal number = $oct"
# 26
# The result of the expression is expressed in decimal.
# ---------------------------

# Hexadecimal: Numbers starting with'0x'or'0X'
# Hexadecimal 0x32 is 60
let "hex = 0x32"
echo "hexadecimal number = $hex"
# 50
# The result of the expression is expressed in decimal.

# Other Binary: BASE#NUMBER
# BASE ranges from 2 to 64.
# NUMBER values must be represented by symbols in the BASE range, as shown in the following example.

# Binary
let "bin = 2#111100111001101"
echo "binary number = $bin"
# 31181

let "b32 = 32#77"
echo "base-32 number = $b32"
# 231

let "b64 = 64#@_"
echo "base-64 number = $b64"
# 4031
# This representation can only work within a limited ASCII character range (2 - 64).
# 10 digits + 26 lowercase letters + 26 uppercase characters + @ + _


echo

echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))

# 1295 170 44822 3375


# Important considerations:
# ---------------
# Using a number that exceeds the given number,
#+will cause an error.

let "bad_oct = 081"
# (partial) error message output:
# bad_oct = 081: value too great for base (error token is "081")
#Octal numbers use only digits in the range 0 - 7.

exit 0
andrew@andrew:/work/bash/src$ 
andrew@andrew:/work/bash/src$ shellcheck numbers.sh 
andrew@andrew:/work/bash/src$ bash numbers.sh 
decimal number = 32
octal number = 26
hexadecimal number = 50
binary number = 31181
base-32 number = 231
base-64 number = 4031

1295 170 44822 3375
numbers.sh: Line 56: let: bad_oct = 081: Numeric value too large to be base of arithmetic digit (The error symbol is "081")
370 original articles have been published. 153. Visits 340,000+
His message board follow

Keywords: shell ascii

Added by killerz on Wed, 01 Apr 2020 09:34:59 +0300