bash的算术运算

作者: CodingCode | 来源:发表于2018-10-14 12:46 被阅读5次

    bash的算术运算

    bash共支持三种算术运算方式

    1. let 表达式
    2. expr 表达式
    3. 双括号表达式
    1. let表达式:let var=<expression>

    let表达式的第一个参数通常时一个变量,把运算表达式的结果存入变量。

    #!/bin/bash
    
    x=3
    y=5
    
    let z1=3+5;         echo $z1    # output: 8, notice no whitespace is allowed.
    # let z = 3 + 5    # invalid
    let "z2=3+5";       echo $z2    # output: 8
    let "z3 = 3 + 5 ";  echo $z3    # output: 8
    
    let z1=x+y;         echo $z1    # output: 8
    # let z = x + y # invalid
    let "z2=x+y";       echo $z2    # output: 8
    let "z3 = x + y ";  echo $z3    # output: 8
    
    let z1=$x+$y;       echo $z1    # output: 8
    # let z = $z + $y # invalid
    let "z2=$x+$y";     echo $z2    # output: 8
    let "z3 = $x + $y"; echo $z3    # output: 8
    

    注意到,如果表达式没有用引号括起来,那么表达式中间不能有空格,这是因为,如果没有引号,那么表达式是由shell先来解析,shell无法识别含义,而如果带引号,那么shell只负责解析整个引号串作为字符串传递给let解析就可以了。

    还支持自增模式:

    #!/bin/bash
    x=3
    y=5
    
    let x+=3;       echo $x    # output: 6
    let "x++";      echo $x    # output: 7
    let "x += y";   echo $x    # output: 12
    let "x+=$y";    echo $x    # output: 17
    
    1. expr表达式:expr <item1 operator item2>

    expr和let的差异是,expr并不把结果写到变量中,而是直接输出到屏幕;所以expr通常使用在表达式中,而不是一个独立的语句。

    #!/bin/bash
    
    x=3
    y=5
    
    expr 3+5        #output: 3+5
    expr 3 + 5      #output: 8
    expr "3+5"      #output: 3+5
    expr "3 + 5"    #output: 3 + 5
    expr "x+y"      #output: x+y
    expr "x + y"    #output: x + y
    expr $x+$y      #output: 3+5
    expr $x + $y    #output: 8
    expr "$x+$y"    #output: 3+5
    expr "$x + $y"  #output: 3 + 5
    

    哈哈,对照let语句,这么多写法,只有两条满足我们的需求,可见expr的使用就有限制的多了:

    1. 不能使用引号把表达式括起来。
    2. 算术运算符之间必须用空格分开。

    不过如果好把expr的结果写到变量中 ,可以使用$()格式。

    #!/bin/bash
    
    x=3
    y=5
    
    z=$(expr $x + $y); echo $z  #output: 8
    
    1. 双括号运算: $(( expression ))

    双括号运行既可以赋值给变量,也可以输出到屏幕:

    #!/bin/bash
    
    x=3
    y=5
    
    ((z=3+5));          echo $z # output: 8
    ((z = 3 + 5));      echo $z # output: 8
    (( z = 3 + 5 ));    echo $z # output: 8
    
    ((z=x+y));          echo $z # output: 8
    ((z = x + y));      echo $z # output: 8
    (( z = x + y ));    echo $z # output: 8
    
    ((z=$x+$y));        echo $z # output: 8
    ((z = $x + $x));    echo $z # output: 8
    (( z = $x + $y ));  echo $z # output: 8
    

    或者

    #!/bin/bash
    
    x=3
    y=5
    
    z=$((3+5));         echo $z # output: 8
    z=$((3 + 5));       echo $z # output: 8
    z=$(( 3 + 5 ));     echo $z # output: 8
    
    z=$((x+y));         echo $z # output: 8
    z=$((x + y));       echo $z # output: 8
    z=$(( x + y ));     echo $z # output: 8
    
    z=$(($x+$y));       echo $z # output: 8
    z=$(($x + $y));     echo $z # output: 8
    z=$(( $x + $y ));   echo $z # output: 8
    

    可支持自增型运算:

    #!/bin/bash
    
    x=3
    y=5
    
    (( x++ ));          echo $x # output: 4,注意这里没有$
    (( y += 1 ));       echo $y # output: 6
    

    作为表达式使用:

    #!/bin/bash
    
    x=3
    y=5
    
    echo "z1="$((x+y))          # output: 8
    echo "z2="$((x++))          # output: 3
    echo "z3="$((++y))          # output: 6
    echo "x=$x,y=$y"            # x=4,y=6
    
    echo "z4="$(($x+$y))          # output: 10
    #echo "z5="$(($x++))          # invalid express
    echo "z6="$((++$y))           # output: 6
    echo "x=$x,y=$y"              # x=4,y=6
    

    这个地方需要注意:

    1. z2输出的是3,因为x++是后增型的,先输出x=3,然后计算x=x+1=4
    2. z3输出的是6,因为++y是先增型的,先计算y=y+1=6,然后输出z3=6
    3. z5是无效的,为什么?
    4. z6输出是4,为什么?
    5. 最后输出x=4,y=6,为什么y也等于6,前面不是++了吗?

    注意z4,z5,z6的表达式中并没有使用双括号'(())'变量,而是使用了shell变量,这个变量表达式在传给双括号'(())'之前,已经被shell替换成了常量4或者6,这相当于在常量上做自增计算,结果自然是无效的。

    因为其实际执行的是:

    echo "z4="$((4+6))          # output: 10
    #echo "z5="$((4++))          # invalid express
    echo "z6="$((++6))           # output: 6
    echo "x=$x,y=$y"              # x=4,y=6
    

    相当于在常量上做自增操作。
    但是还是有疑问的是,为什么常量上可以做先自增操作,而不能做后自增操作。

    相关文章

      网友评论

        本文标题:bash的算术运算

        本文链接:https://www.haomeiwen.com/subject/mgszaftx.html