注意:变量尽量用双引号引起来
对于值为非空的变量无所谓,对于值为空的变量,很可能出问题
一、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
网友评论