一、执行数学运算
1、expr命令
例:
[root@CHENDAJIE ~]# expr 1 + 5
6
expr 命令可以识别少数的数学和字符串操作符,如下图:
书上列出的表格里面还有一些字符串匹配的,但是我现在并不是很了解,所以暂时没有列出来(详情请见223面)
如上图所示,expr已经足够支持大多数运算,但是在脚本或命令行使用是仍有时会出现问题。
例如:
[root@CHENDAJIE ~]# expr 5 * 2
expr: 语法错误
要解决这个问题的话,需要借助转义字符( \ )将其标出来
[root@CHENDAJIE ~]# expr 5 \* 2
10
在shell脚本中使用expr命令:
[root@CHENDAJIE sh.test]# cat test7.sh
#!/bin/bash
# An example of using the expe command
var1=10
var2=20
var3=$(expr $var2 / $var1)
echo The result is $var3
[root@CHENDAJIE sh.test]# chmod u+x test7.sh
[root@CHENDAJIE sh.test]# ./test7.sh
The result is 2
值得注意的是:此时如果你需要将算术运算的结果赋给一个变量,需要使用命令来替换expr命令的输出。
2、使用方括号
例:
[root@CHENDAJIE sh.test]# var1=$[1 + 5]
[root@CHENDAJIE sh.test]# echo $var1
6
[root@CHENDAJIE sh.test]# var2=$[$var1 * 2]
[root@CHENDAJIE sh.test]# echo $var2
12
在shell脚本中使用方括号
[root@CHENDAJIE sh.test]# cat test8.sh
#!/bin/bash
#
var1=100
var2=50
var3=45
var4=$[$var1 * ($var2 - $var3)]
echo The final result is $var4
[root@CHENDAJIE sh.test]# chmod u+x test8.sh
[root@CHENDAJIE sh.test]# ./test8.sh
The final result is 500
方括号在bash shell脚本中运行的主要限制:
[root@CHENDAJIE sh.test]# cat test9.sh
#!/bin/bash
#
var1=100
var2=45
var3=$[$var1 / $var2]
echo The final result is $var3
[root@CHENDAJIE sh.test]# chmod +x test9.sh
[root@CHENDAJIE sh.test]# ./test9.sh
The final result is 2
可以看到,此处没有显示小数,只支持整数运算。
二、浮点解决方案
有几种解决方案可以克服bash中数学运算的整数限制,最常见的方案是用内建的bash计算机。
1、bc的基本用法
bash计算机实际上是一种编程语言,它允许在命令行中输入浮点表达式,然后解释并计算该表达式,最后返回结果,。bash计算机能够识别:
* 数字(整数和浮点数)
* 变量(简单的变量和数组)
* 注释(以#或C语言中的/* */开始的行)
* 表达式
* 编程语句(例如if-then语句)
* 函数
可以在shell提示符下通过bc命令访问bash计算器
例:
[root@CHENDAJIE sh.test]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
3.156 * (3 + 5)
25.248
quit
要退出bc计算器,你必须输入quit。
浮点运算是由内建命令scale控制的。必须将这个值设置为你希望在计算结果中保留的小数位,否则是无法得到期望的结果。
例:
[root@CHENDAJIE sh.test]# bc -q
3.44 / 5
0
scale=4
3.44 / 5
.6880
quit
2、在脚本中使用bc
基本格式如下:
variable=$(echo “option(选项); expression(表达式)” | bc)
例:
[root@CHENDAJIE sh.test]# cat test10.sh
#/bin/bash
#
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The answer is $var1
[root@CHENDAJIE sh.test]# chmod u+x test10.sh
[root@CHENDAJIE sh.test]# ./test10.sh
The answer is .6880
现在,我们重新写一个计算100 / 45 的脚本,如下所示:
[root@CHENDAJIE sh.test]# cat test11.sh
#/bin/bash
#
var1=100
var2=45
var3=$(echo "scale=4; $var1 / $var2" | bc)
echo The anwer for this is $var3
[root@CHENDAJIE sh.test]# chmod u+x test11.sh
[root@CHENDAJIE sh.test]# ./test11.sh
The anwer for this is 2.2222
脚本定义了两个变量,它们都可以在expression部分,然后发送给bc命令。
同时,当变量被赋值时,那个变量也可以用于其他运算:
例:
[root@CHENDAJIE sh.test]# cat test12.sh
#/bin/bash
#
var1=20
var2=3.14159
var3=$(echo "scale=4; $var1 * $var1" | bc)
var4=$(echo "scale=4; $var3 * $var2" | bc)
echo The final result is $var4
[root@CHENDAJIE sh.test]# chmod u+x test12.sh
[root@CHENDAJIE sh.test]# ./test12.sh
The final result is 1256.63600
bc命令能够识别输入重定向,允许将一个文件重定向到bc命令来处理。同时还支持内联输入重定向,在shell脚本中,你可以将输出赋给一个变量
格式如下:
variable=$(bc << EOF
optionfs
statements
expressions
EOF
)
EOF文本字符串标识了内联重定向数据的起止。值得注意的是,仍然需要命令替换符号将bc命令的输出赋给变量。
例:
[root@CHENDAJIE sh.test]# cat test13.sh
#/bin/bash
#
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale = 4
a1 = ( $var1 * $var2)
b1 = ( $var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5
[root@CHENDAJIE sh.test]# chmod u+x test13.sh
[root@CHENDAJIE sh.test]# ./test13.sh
The final answer for this mess is 2813.9882
在bash计算器中创建的变量只在bash计算器中有效,不能再shell脚本中使用
三、退出脚本
1、查看退出状态码
Linux中提供了一个专门的变量
?
来
保
存
上
个
已
执
行
命
令
的
退
出
状
态
码
。
对
于
需
要
进
行
检
查
的
命
令
,
必
须
在
其
运
行
完
毕
后
立
刻
查
看
或
使
用
?来保存上个已执行命令的退出状态码。对于需要进行检查的命令,必须在其运行完毕后立刻查看或使用
?来保存上个已执行命令的退出状态码。对于需要进行检查的命令,必须在其运行完毕后立刻查看或使用?变量,它的值会变成由shell所执行的最后一条命令的退出状态码。
例:
[root@CHENDAJIE sh.test]# date
2019年 10月 09日 星期三 16:02:24 CST
[root@CHENDAJIE sh.test]# echo $?
0
当退出状态码为0时,表明命令成功结束。
当退出状态码是正数时,表明命令结束时错误。
[root@CHENDAJIE sh.test]# dsadawa
bash: dsadawa: 未找到命令...
[root@CHENDAJIE sh.test]# echo $?
127
常用的退出状态码参考:
0 | 命令成功结束 |
---|---|
1 | 一般性未知错误 |
2 | 不适合的shell命令 |
126 | 命令不可执行 |
127 | 没找到命令 |
128 | 无效的退出参数 |
128+x | 与Linux信号x相关的严重错误 |
130 | 通过Ctrl+C终止的命令 |
2、exit命令
默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出。
[root@CHENDAJIE sh.test]# ./test7.sh
The result is 2
[root@CHENDAJIE sh.test]# echo $?
0
exit命令允许你在脚本结束时指定一个退出状态码。
例:
[root@CHENDAJIE sh.test]# cat test14.sh
#!/bin/bash
# Testing the exit status
var1=10
var2=30
var3=$[$var1 + $var2]
echo The answer is $var3
exit 5
[root@CHENDAJIE sh.test]# chmod u+x test14.sh
[root@CHENDAJIE sh.test]# ./test14.sh
The answer is 40
[root@CHENDAJIE sh.test]# echo $?
5
可以看到,此时输入echo $?返回的命令状态退出码是我们自己定义的5;
也可以在exit命令的参数中使用变量
[root@CHENDAJIE sh.test]# cat test15.sh
#!/bin/bash
# Testing the exit stasus
var1=10
var2=30
var3=$[$var1 + $var2]
exit $var3
[root@CHENDAJIE sh.test]# chmod u+x test15.sh
[root@CHENDAJIE sh.test]# ./test15.sh
[root@CHENDAJIE sh.test]# echo $?
40
可以看到,此时命令状态退出码为40;
【注意】:
命令状态退出码的区间是0–255,当自己定义的状态退出码大于255时。得出的状态码等于指定的数值除以256之后的余数。
例:
[root@CHENDAJIE sh.test]# cat test15b.sh
#!/bin/bash
# Testing the exit status
var1=10
var2=30
var3=$[$var1 * $var2]
echo The value is $var3
exit $var3
[root@CHENDAJIE sh.test]# chmod u+x test15b.sh
[root@CHENDAJIE sh.test]# ./test15b.sh
The value is 300
[root@CHENDAJIE sh.test]# echo $?
44
例子中可以看到,此时var3的值为300,但是返回的状态码是44.