SHELL脚本编程的运算符

         SHELL脚本编程的运算符

                             作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

 

一.算数运算
1>.bash中的算数运算
[root@node101.yinzhengjie.org.cn ~]# help let
let: let arg [arg ...]
    Evaluate arithmetic expressions.
    
    Evaluate each ARG as an arithmetic expression.  Evaluation is done in
    fixed-width integers with no check for overflow, though division by 0
    is trapped and flagged as an error.  The following list of operators is
    grouped into levels of equal-precedence operators.  The levels are listed
    in order of decreasing precedence.
    
        id++, id--    variable post-increment, post-decrement
        ++id, --id    variable pre-increment, pre-decrement
        -, +        unary minus, plus
        !, ~        logical and bitwise negation
        **        exponentiation
        *, /, %        multiplication, division, remainder
        +, -        addition, subtraction
        <<, >>        left and right bitwise shifts
        <=, >=, <, >    comparison
        ==, !=        equality, inequality
        &        bitwise AND
        ^        bitwise XOR
        |        bitwise OR
        &&        logical AND
        ||        logical OR
        expr ? expr : expr
                conditional operator
        =, *=, /=, %=,
        +=, -=, <<=, >>=,
        &=, ^=, |=    assignment
    
    Shell variables are allowed as operands.  The name of the variable
    is replaced by its value (coerced to a fixed-width integer) within
    an expression.  The variable need not have its integer attribute
    turned on to be used in an expression.
    
    Operators are evaluated in order of precedence.  Sub-expressions in
    parentheses are evaluated first and may override the precedence
    rules above.
    
    Exit Status:
    If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# help let
+, -, *, /, %取模(取余), **(乘方),乘法符号有些场景中需要转义。

实现算术运算:
  (1) let var=算术表达式
  (2) var=$[算术表达式]
  (3) var=$((算术表达式))
  (4) var=$(expr arg1 arg2 arg3 ...)
  (5) declare –i var = 数值
  (6) echo ‘算术表达式’ | bc

增强型赋值:
  +=, -=, *=, /=, %=

let varOPERvalue
  例如:let count+=3
  自加3后自赋值

自增,自减:
  let var+=1
  let var++
  let var-=1
  let var--
[root@node101.yinzhengjie.org.cn ~]# x=3
[root@node101.yinzhengjie.org.cn ~]# y=8
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# let num=$x*$y
[root@node101.yinzhengjie.org.cn ~]# echo $num
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# let num=x*y
[root@node101.yinzhengjie.org.cn ~]# echo $num
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo $[x-y]
-6
[root@node101.yinzhengjie.org.cn ~]# echo $[x**y]
[root@node101.yinzhengjie.org.cn ~]# echo $[y%x]
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# i=10
[root@node101.yinzhengjie.org.cn ~]# echo $i
10
[root@node101.yinzhengjie.org.cn ~]# ((i++))           #等价于i=i+1,表示要先使用i变量后,在对其进行加1操作。
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo $i
11
[root@node101.yinzhengjie.org.cn ~]# unset i
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# m=10
[root@node101.yinzhengjie.org.cn ~]# let ++m          #在循环中使用会需要先对m变量进行加1在使用它。
[root@node101.yinzhengjie.org.cn ~]# echo $m
11
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo $x
2
[root@node101.yinzhengjie.org.cn ~]# echo $y
8
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# expr $x * $y
16
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# declare -i m=10
[root@node101.yinzhengjie.org.cn ~]# declare -i n=20
[root@node101.yinzhengjie.org.cn ~]# declare -i num=m+n
[root@node101.yinzhengjie.org.cn ~]# echo $num
30
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo "100 * 2" | bc
200
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# x=10
[root@node101.yinzhengjie.org.cn ~]# let x+=2
[root@node101.yinzhengjie.org.cn ~]# echo $x
12
[root@node101.yinzhengjie.org.cn ~]# let x-=4
[root@node101.yinzhengjie.org.cn ~]# echo $x
8
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# let x/=3               #不支持浮点数,因此除等得到的值只能取整数。
[root@node101.yinzhengjie.org.cn ~]# echo $x
2
[root@node101.yinzhengjie.org.cn ~]# 
算术运算符测试案例
2>.bash有内建的随机生成器变量:"$RANDOM(0-32767)"
[root@node101.yinzhengjie.org.cn ~]# man bash            #保存了BASH中默认存在的变量,RANDOM只是其中之一。
[root@node101.yinzhengjie.org.cn ~]# echo $RANDOM
5250
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo $RANDOM
2602
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo $RANDOM                 #默认生成 0 - 32767 之间随机数
29339
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo $[$RANDOM%50]        #生成 0 - 49 之间随机数
47
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo $[$RANDOM%50]        
36
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# echo $[$RANDOM%50]
32
[root@node101.yinzhengjie.org.cn ~]# 
3>.declare声明变量类型
4>.数值运算 
5>.expr或let数值运算工具
6>.“$((运算式))”或"$[运算式]"
7>.运算符
8>.小试牛刀
(1)编写脚本 sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的UID之和
(2)编写脚本 sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
(3)编写脚本 sumfile.sh,统计/etc, /var, /usr 目录中共有多少个一级子目录和文件
 
二.逻辑运算
1>.位与(&)
与运算只能是二进制的操作,任何数和0相与,结果为0,任何数和1相与,保留原值。

举例,请将十进制的12和8进行与运算。
  首先将12和8转换成二进制,如下所示:
    12 ------> 0b0000 1100
    8  ------> 0b0000 1000
  得到的最终结果为:0b0000 1000,即12&8=8
2>.位或(|)
与运算只能是二进制的操作,两个数字只要有1,结果为1,两个书数字都为0,结果才为0。

举例,请将十进制的12和8进行或运算。
  首先将12和8转换成二进制,如下所示:
    12 ------> 0b0000 1100
    8  ------> 0b0000 1000
  得到的最终结果为:0b0000 1100,即12|8=12
3>.非(!)
非操作就是取反,如:
  !1 = 0,即1(true)的非为0(false)。
  !0 = 1,即0(false)的非为1(true)。
4>.短路运算
短路与(&&):
  举例:我们将0表示为假,1表示为真,则有以下关系:
    假与真=假(0&&1=0)
    假与假=假(0&&0=0)
    真与真=真(1&&1=1)
    真与假=假(1&&0=0)
  
  总结:
    CMD1 && CMD2
    如果与前面的CMD1执行是假,结果必定是假,没有必要执行与后的操作CMD2。反之,则CMD2要参加运算。

短路或(||):
  举例:我们将0表示为假,1表示为真,则有以下关系:
    真或真=真(1||1=1)
    真或假=真(1||0=1)
    假或真=真(0||1=1)
    假或假=假(0||0=0)

  总结:
    CMD1 || CMD2
    如果或前面的CMD1执行结果是真,结果必定是真,没有必要执行或后的操作CMD2。反正,则CMD2要参与运算。
5>.异或(^)
  举例:我们将0表示为假,1表示为真,则有以下关系:
    假异或假=假(0^0=0)
    假异或真=真(0^1=1)
    真异或假=真(1^0=1)
    真异或真=假(1^1=0)

  总结:
    异或的两个值,相同为假,不同为真。

  小试牛刀:请将十进制的12和8进行异或运算。
    首先将12和8转换成二进制,如下所示:
      12 ------> 0b0000 1100
      8  ------> 0b0000 1000
    得到的最终结果为:0b0000 0100,即12^8=4。由此可迅速推断出4^8=12,4^12=8。
[root@node101.yinzhengjie.org.cn ~]# x=100;y=200;tmp=$x;x=$y;y=$tmp;echo x=$x,y=$y        #借助于中间变量
x=200,y=100
[root@node101.yinzhengjie.org.cn ~]# 
[root@node101.yinzhengjie.org.cn ~]# x=100;y=200;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y    #借助于异或运算,效率更好,因为是基于二进制的。
x=200,y=100
[root@node101.yinzhengjie.org.cn ~]# 
变量互换案例(将x=100,y=200变为y=100,x=200)
原文地址:https://www.cnblogs.com/yinzhengjie/p/7637847.html