得之我幸 失之我命

when someone abandons you,it is him that gets loss because he lost someone who truly loves him but you just lost one who doesn’t love you.

shell 中的整数运算

话在前头,为什么本文是整数运算,因为 bash 本身不支持浮点型的运算,换言之,bash 本身能做的也就整数类型的运算

谈一谈在 shell 中进行整数运算的几种方案

  1. r=$((1+2*3))
  2. r=`expr 1 \+ 2 \* 3`
  3. r=$[1+2] |
  4. declare -i r=1+2*3 |
  5. let r=1+2 |

$((算术式))

  1. 如果表达式中有变量,该变量之前最好不要加 $ 符号,以免变量不存在造成语法错误

    例:

    1
    2
    3
    4
    5
    $ unset i
    $ echo $((2+$i)) # 由于 i 不存在,所以会变成 echo $((2+)),语法就错误了
    -bash: 2+: syntax error: operand expected (error token is "+")
    $ echo $((2+i)) # ((2+i)) 是一个合法的算术式,就算变量不存在,仍可正确计算
    2
  2. 注意和 (()) 的区别

外部程序 expr 算术式

  1. 数字与符号之间要有空白

    例:

    1
    2
    3
    4
    5
    6
    $ echo `expr 2%3`
    2%3
    $ echo `expr 2 %3`
    expr: syntax error: unexpected argument ‘%3’
    $ echo `expr 2 % 3`
    2
  2. 没有乘幂

    例:

    1
    2
    3
    4
    $ echo `expr 2 \*\* 3`
    expr: syntax error: unexpected argument ‘**’
    $ echo `expr 2 \** 3`
    expr: syntax error: unexpected argument ‘**’
  3. 乘号要用转义符

    例:

    1
    2
    3
    4
    $ echo `expr 2 * 3`
    expr: syntax error: unexpected argument ‘’
    $ echo `expr 2 \* 3`
    6
  4. expr 是外部程序

  5. 表达式中包含 shell 的特殊字符,如 *、|、<、>、!、&、(、),要使用 \ 来转义

$[]

  1. 空格无影响

内置命令 declare -i

  1. bash shell 的内置命令

  2. 使用 declare 命令的 -i 选项可以将一个变量声明为整数类型,这样在进行数学计算时就不会作为字符串处理,除了将参与运算的变量定义为整数,还得将承载结果的变量定义为整数,而且只能用整数类型的变量来承载运算结果,不能直接使用 echo 输出

    例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ declare -i m n
    $ m=10
    $ n=30
    $ ret=$m+$n
    $ echo $ret
    10+30

    $ declare -i ret # 除了将 m、n 定义为整数,还必须将 ret 定义为整数,如果不这样做,在执行 ret=$m+$n和ret=$n/$m 时,Shell 依然会将 m、n 视为字符串
    $ ret=$m+$n
    $ echo $ret
    40

    $ echo $m+$n # 不能写类似 echo $m+$n 这样的语句,这种情况下 m、n 会被视为字符串
    10+30
  3. 仅支持最基本的数学运算(加减乘除和取余),不支持逻辑运算(比较运算、与运算、或运算、非运算),在实际开发中很少使用

内置命令 let

  1. bash shell 的内置命令

  2. 变量和运算符直接不能有空格,否则要用引号

  3. let 后面可以跟多个表达式

be yourself, everyone else is already taken.