美文网首页
Bash 基本运算和变量

Bash 基本运算和变量

作者: Manchangdx | 来源:发表于2018-07-24 20:03 被阅读0次

    注意:变量尽量用双引号引起来
    对于值为非空的变量无所谓,对于值为空的变量,很可能出问题

    一、expr 为内置命令,只对整数进行运算(注意空格)

    1.1 四则运算(只有 + - * / % ± 这些符号可用)

    zds@ubuntu:~$ expr 8 + 9
    17
    zds@ubuntu:~$ expr -9 + 3
    -6
    zds@ubuntu:~$ expr 3 \* 22  # 乘号需转义
    66
    zds@ubuntu:~$ expr 22 % 9  # 取余数
    4
    zds@ubuntu:~$ expr 123 / 12 - 3
    7
    zds@ubuntu:~$ a=5
    zds@ubuntu:~$ expr $a / -2
    -2
    

    1.2 逻辑运算:或 |&!(前两者须转义,后者须配合 = 使用)
    注意命令的返回值(即运算结果)和退出状态码的区别

    zds@ubuntu:~$ expr 9 \| 3  # 两者都不为 0 结果取前者,退出状态码为 0
    9
    zds@ubuntu:~$ expr 3 \| 9
    3
    zds@ubuntu:~$ expr 0 \| 0  # 若两个都为 0 结果为 0,退出状态码为 1
    0
    zds@ubuntu:~$ expr 0 \| 5  # 若有一个为 0 结果取另一个的值,退出状态码为 0
    5
    zds@ubuntu:~$ expr 5 \| 0
    5
    
    zds@ubuntu:~$ expr 4 \& 9  # 两者都不为 0 结果取前者,退出状态码为 0
    4
    zds@ubuntu:~$ expr 9 \& 4
    9
    zds@ubuntu:~$ expr 0 \& 0  # 两者若有一个为 0 结果即为 0,退出状态码为 1
    0
    zds@ubuntu:~$ expr 111 \& 0
    0
    zds@ubuntu:~$ expr 0 \& 111
    0
    
    zds@ubuntu:~$ expr 9 != 3  # 逻辑为真结果是 1,退出状态码为 0
    1
    zds@ubuntu:~$ expr 9 != 7 + 2  # 逻辑为假结果是 0,退出状态码为 1
    0
    zds@ubuntu:~$ expr 9 = 3 \* 3  # 逻辑为真结果是 1,退出状态码为 0
    1
    

    1.3 关系运算<> 须转义)
    注意:下面说的都是运算结果(即命令返回值),而不是退出状态码

    zds@ubuntu:~$ expr 9 \< 9  # 关系为假结果是 0
    0
    zds@ubuntu:~$ expr 8 \>= 3 \* 3
    0
    zds@ubuntu:~$ expr 8 \>= 2 \* 3  # 关系为真结果是 1
    1
    zds@ubuntu:~$ expr -45 / 11 = -4  # 一个等号和俩等号都是判断左右是否相等
    1
    zds@ubuntu:~$ expr 3 == 3  # macOS 中不能使用俩等号
    1
    

    二、(( )) 依然只对整数进行运算

    相较 expr 要人性化,不必转义特殊符号,不必加空格

    zds@ubuntu:~$ ((a=(2+3)*4))  # 可用使用括号
    zds@ubuntu:~$ echo $a
    20
    zds@ubuntu:~$ a=0
    zds@ubuntu:~$ echo $a
    0
    zds@ubuntu:~$ ((a+=3))
    zds@ubuntu:~$ echo $a
    3
    zds@ubuntu:~$ ((a=a*4))
    zds@ubuntu:~$ echo $a
    12
    zds@ubuntu:~$ ((a/=5))
    zds@ubuntu:~$ echo $a
    2
    zds@ubuntu:~$ ((a++))  # 加 1
    zds@ubuntu:~$ echo $a
    3
    zds@ubuntu:~$ ((a--))  # 减 1
    zds@ubuntu:~$ echo $a
    2
    zds@ubuntu:~$ echo $((9*-4/6))  # 固定写法
    -6
    zds@ubuntu:~$ echo $((3**4))  # 幂运算
    81
    zds@ubuntu:~$ echo $((2#101))  # 把井号后面的数当作二进制来处理,将之转换为十进制
    5
    

    三、let(( )) 一样

    zds@ubuntu:~$ a=0
    zds@ubuntu:~$ let a-=9
    zds@ubuntu:~$ echo $a
    -9
    zds@ubuntu:~$ let a=(89-33)*7
    zds@ubuntu:~$ echo $a
    392
    

    四、declare -i 使变量数值化

    zds@ubuntu:~$ num=2+3
    zds@ubuntu:~$ echo $num
    2+3
    zds@ubuntu:~$ declare -i num  # 使 num 变量的值数值化
    zds@ubuntu:~$ echo $num
    2+3
    zds@ubuntu:~$ num=9/4
    zds@ubuntu:~$ echo $num
    2
    zds@ubuntu:~$ num=ok  # 赋值字符串,无法计算,结果为 0
    zds@ubuntu:~$ echo $num
    0
    

    五、bc 属于外部命令,可用 sudo apt install bc 安装

    5.1 bc 可运算小数
    结果小数位数等于算术式中数值的小数位数的最大值

    zds@ubuntu:~$ echo '2+2' | bc
    4
    zds@ubuntu:~$ echo '(3+2.4)*7' | bc  
    37.8
    zds@ubuntu:~$ echo '(-36%7)**3--5.5' | bc  # 不可连续两个减号
    (standard_in) 1: syntax error
    zds@ubuntu:~$ echo '(-36%7)**3-(-5.5)' | bc  # 不可进行幂运算
    (standard_in) 1: syntax error
    zds@ubuntu:~$ echo '(-36%7)*3-(-5.5)' | bc
    2.5
    

    5.2 交互界面,按 Ctrl + D 退出

    zds@ubuntu:~$ bc
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'. 
    (8*8-9)/3.3
    16
    scale=2  # 默认保留 0 位小数,设置小数位数为 2,只对乘除有效
    (8*8-9)/3.3
    16.66
    

    六、条件判断

    6.1 Shell 中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试

    6.1.1 test 比较两个整数值,[ ] 等同于 test,注意只能比较一位数
    -gt \> 大于,-lt \< 小于,-ge 大于等于,-le 小于等于
    -eq = == 等于,-ne != 不等于:

    mcdx@ubuntu:~$ test 2 -gt 3  
    mcdx@ubuntu:~$ echo $?  # 获取上次命令的返回值,结果为假返回值为 1
    1
    mcdx@ubuntu:~$ test 34 -lt 91
    mcdx@ubuntu:~$ echo $?  
    0
    mcdx@ubuntu:~$ [ 3 -eq 3 ]
    mcdx@ubuntu:~$ echo $?
    0
    mcdx@ubuntu:~$ read a b
    1 1
    mcdx@ubuntu:~$ if [ $a == $b ]; then echo '俩数相等'; fi
    俩数相等
    mcdx@ubuntu:~$ read a b 
    1 2
    mcdx@ubuntu:~$ if [ $a -le $b ]; then echo 'a 小于等于 b'; fi
    a 小于等于 b
    mcdx@ubuntu:~$ read a b
    1 '1'
    mcdx@ubuntu:~$ if [ $a = $b ]; then echo '俩数相等'; else echo '俩数不等'; fi
    俩数不等
    

    6.1.2 test [ ] 判断字符串
    -eq = == 等于,-ne != 不等于,-n 长度不为零,-z 长度为零:

    mcdx@ubuntu:~$ read a
    
    mcdx@ubuntu:~$ echo $a  # 体现了引用变量加双引号的重要性
    
    mcdx@ubuntu:~$ if [ -n $a ]; then echo '长度不为零'; else echo '长度为零'; fi
    长度不为零
    mcdx@ubuntu:~$ if [ -n "$a" ]; then
    > echo '长度不为零'; else
    > echo '长度为零'; fi
    长度为零
    mcdx@ubuntu:~$ read a
    
    # -n 可省略
    mcdx@ubuntu:~$ if [ "$a" ]; then echo '不为空'; else echo '为空'; fi  
    为空  
    mcdx@ubuntu:~$ read a
    12
    mcdx@ubuntu:~$ if [ "$a" ]; then echo '不为空'; else echo '为空'; fi
    不为空
    

    6.1.3 test [ ] 判断文件
    -d 是目录,-e 文件存在,-r 文件可读,-w 文件可写,-x 文件可执行
    -f 普通文件,-s 文件大小不为零,-o 或逻辑,-a 与逻辑
    -O 当前用户是文件的拥有者(以上这些,双中括号不能用):

    mcdx@ubuntu:~$ ls
    Desktop  Documents  Downloads  git  simpledu  test  test.sh
    mcdx@ubuntu:~$ [ -e test.sh ]; echo $?
    0
    mcdx@ubuntu:~$ test -d git; echo $?
    0
    mcdx@ubuntu:~$ test -d test.sh; echo $?
    1
    mcdx@ubuntu:~$ [ -O test.sh ]; echo $?
    0
    mcdx@ubuntu:~$ [ -e test.sh -o -e xxx ]; echo $?
    0
    mcdx@ubuntu:~$ [ -e test.sh -a -e xxx ]; echo $?
    1
    

    6.2 [[ ]] 是比较高级的判断方法(说是高级,其实用法之复杂也让人作呕)
    -gt > 大于,-lt < 小于(<> 只能比较一位数字的大小)
    -ge 大于等于,-le 小于等于,-eq = == 等于,-ne != 不等于
    -n 长度不为零,-z 长度为零,&& 与,|| 或:

    shiyanlou:~/ $ [[ 23 < 123 ]]; echo $?  
    1
    shiyanlou:~/ $ [[ 23 < 24 ]]; echo $?  
    0
    zds@ubuntu:~$ a=1; b=2; c=1
    # 不加 $ 符号也可以,但尽量加上,双引号也尽量加上
    zds@ubuntu:~$ [[ a < b ]]; echo $?  
    0
    zds@ubuntu:~$ [[ a > b ]]; echo $?
    1
    zds@ubuntu:~$ [[ $a < $b ]]; echo $?
    0
    zds@ubuntu:~$ [[ $a > $b ]]; echo $?
    1
    zds@ubuntu:~$ [[ $a <= $b ]]; echo $?  # 这种写法不行,单中括号里也不行
    bash: 条件表达式中有语法错误
    bash: `$b' 附近有语法错误
    
    zds@ubuntu:~$ [[ $a -lt $b ]]; echo $?
    0
    zds@ubuntu:~$ [[ $a -le $b ]]; echo $?
    0
    zds@ubuntu:~$ [[ $a = $c ]]; echo $?
    0
    zds@ubuntu:~$ [[ $a = $b ]]; echo $?
    1
    zds@ubuntu:~$ [[ $a == $c ]]; echo $?
    0
    zds@ubuntu:~$ [[ $a -eq $c ]]; echo $?
    0
    zds@ubuntu:~$ [[ $a != $c ]]; echo $?
    1
    zds@ubuntu:~$ [[ $a -ne $b ]]; echo $?
    0
    zds@ubuntu:~$ [[ -n $a ]]; echo $?
    0
    zds@ubuntu:~$ declare d
    zds@ubuntu:~$ [[ -n $d ]]; echo $?
    1
    zds@ubuntu:~$ [[ -z $d ]]; echo $?
    0
    
    zds@ubuntu:~$ e=hello
    zds@ubuntu:~$ [[ $e = hell? ]]; echo $?  # 问号通配符也能用(别的通配符不行)
    0
    zds@ubuntu:~$ [[ $e == hell? ]]; echo $?
    0
    zds@ubuntu:~$ [[ $e -eq hello ]]; echo $?  # 不可以用 -eq 判断非数值
    0
    zds@ubuntu:~$ [[ $e -eq hellooo ]]; echo $?
    0
    zds@ubuntu:~$ [[ $e = worl? ]]; echo $?
    1
    zds@ubuntu:~$ [[ -n $e && 3 > 2 ]]; echo $?  # 与
    0
    zds@ubuntu:~$ [[ -n $e && 3 = 2 ]]; echo $?
    1
    zds@ubuntu:~$ [[ -n $e || 3 = 2 ]]; echo $?  # 或
    0
    

    =~ 使用正则表达式,前者包含后者,表达式即为真。几个常用的符号:
    ^ 匹配字符串的开始处,$ 匹配字符串的结尾处
    + 匹配一个或多个前面的字符,? 匹配 0 个或 1 个前面的字符
    . 匹配任意一个字符

    mcdx@ubuntu:~$ a=assss
    mcdx@ubuntu:~$ if [[ $a =~ ^as+ ]]; then echo 'ok'; else echo 'not ok'; fi
    ok
    mcdx@ubuntu:~$ if [[ $a =~ ^as ]]; then echo 'ok'; else echo 'not ok'; fi
    ok
    mcdx@ubuntu:~$ if [[ $a =~ ss ]]; then echo 'ok'; else echo 'not ok'; fi
    ok
    mcdx@ubuntu:~$ if [[ $a =~ sst ]]; then echo 'ok'; else echo 'not ok'; fi
    not ok
    mcdx@ubuntu:~$ [[ helloworld =~ world$ ]]; echo $?
    0
    mcdx@ubuntu:~$ [[ helloworld =~ worl$ ]]; echo $?
    1
    mcdx@ubuntu:~$ [[ abc =~ a.c ]]; echo $?
    0
    mcdx@ubuntu:~$ [[ abc =~ a.d ]]; echo $?
    1
    

    七、随机数

    7.1 $RANDOM 可以生成 0-32767 的随机数
    它不是一个变量,是一个内置的函数:

    mcdx@ubuntu:~$ echo $RANDOM
    32058
    mcdx@ubuntu:~$ echo $RANDOM
    170
    mcdx@ubuntu:~$ echo $RANDOM
    17302
    mcdx@ubuntu:~$ expr $RANDOM / 222
    54
    

    7.2 此外,还可以使用 shuf 生成随机数
    -i 指定随机数值的范围,-n 指定随机数的数量

    mcdx@ubuntu:~$ shuf -i 1-10 -n 3
    1
    9
    2
    mcdx@ubuntu:~$ shuf -i 100-1000 -n 4
    835
    460
    454
    599
    

    相关文章

      网友评论

          本文标题:Bash 基本运算和变量

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