bash 数学运算与条件测试

bash 数学运算与条件测试

学习bash脚本编程过程中,发现bash脚本中的运算符,表达式种类繁多,且使用风格各异。现对数学运算和条件测试进行总结。

数学运算

数学运算符

名字 符号 含义
数值运算 +, -, *, /, %, ** 加,减,乘,除,取余,幂
自增,自减运算 ++,– 自增,自减
逻辑运算 &&,||,! 与,或,非
按位运算 &,|,~,^ 位与,位或,位非,位异或
移位运算 <<,>> 位左移,位右移
比较运算 >,>=,<,<=,==,!= 大于,大于等于,小于,小于等于,等于,不等于
赋值运算 =,+=,-=,*=,/=,%= 赋值,运算并赋值

数学运算命令

  • (())
  • let
  • $[]
  • bc

(())

  1. 语法 ((EXPRESION))
    EXPRESSION 由以下部分组成

    • 数值运算
    • 逻辑运算
    • 比较运算
    • 按位运算
    • 位移运算
    • 赋值运算
  2. $(()) 将运算结果赋值给其它变量
    (()) 运算并不会输出任何结果,若将运算的结果赋值给其它变量,则使用$(())

  3. (()), $[], let 三者的对应关系
    ((EXPRESION)) 等同于 let "EXPRESION"
    $((EXPRESION)) 等同于 $[EXPRESION]

实例: 编写脚本实现输入两个整数,进行四则运算

[root@CentOS6 app]# cat four_arithmetic_operations.sh 
#!/bin/bash

#---------------------------------------
# Author: zhuenbiao
# File Name: four_arithmetic_operations.sh
# Create Time: 2017-08-26 17:29:15
# Modified Time: 2017-08-26 17:29:15
# Version: 0.1
# Description:
#---------------------------------------


# Check whether integer of inputed numbers
repaty=1
until [[ "$num1" =~ ^[0-9]+$ && "$num2" =~ ^[0-9]+$ ]];do
echo "Please input two integer"
read -p "num1= " num1
read -p "num2= " num2

if [ "$repaty" -eq 4 ];then
break;
fi

((repaty++))
done

# Addition
sum=$((num1+num))
echo "$num1+$num2=$sum"

# Subtraction
((difference=num1-num2))
echo "$num1-$num2=$difference"

# Multiplication
product=$(($num1*$num2))
echo "$num1*$num2=$product"

# Division
quotient=$(( num1 / num2))

输出结果如下:

[root@CentOS6 app]# bash four_arithmetic_operations.sh 
Please input two integer
num1= 20 <=输入20
num2= 8 <=输入8
20+8=20
20-8=12
20*8=160
20/8=2

let

  1. 语法 let “EXPRESION”
    EXPRESSION 由以下部分组成

    • 数值运算
    • 逻辑运算
    • 比较运算
    • 按位运算
    • 位移运算
    • 赋值运算
  2. let "EXPRESSION" 等同于 ((EXPRESSION))

# 加法运算
[root@CentOS6 app]# num1=10
[root@CentOS6 app]# num2=20
[root@CentOS6 app]# let sum=num1+num2
[root@CentOS6 app]# echo $sum
30
# 自增运算
[root@CentOS6 app]# let ++sum
[root@CentOS6 app]# echo $sum
31
# 按位异或运算
[root@CentOS6 app]# let result=num1^num2
[root@CentOS6 app]# echo $result
30
# 比较运算
[root@CentOS6 app]# let "num1 > num2"
[root@CentOS6 app]# echo $?
1
[root@CentOS6 app]# let "num1 != num2"
[root@CentOS6 app]# echo $?
0
[root@CentOS6 app]#

$[]

  1. 语法 $[EXPRESSION]
    EXPRESSION 由以下部分组成

    • 数值运算
    • 逻辑运算
    • 比较运算
    • 按位运算
    • 位移运算
    • 赋值运算
  2. $[EXPRESSION] 等同于 $((EXPRESSION))

# 赋值运算
[root@CentOS6 app]# num1=10
[root@CentOS6 app]# echo $[num1+=5]
15
# 位移运算
[root@CentOS6 app]# num2=3
[root@CentOS6 app]# echo $[num2<<1]
6
# 比较运算
[root@CentOS6 app]# echo $[5<=6]
1

bc
以上所介绍的运算符均只能运算整数,若要进行浮点数的运算,可以使用命令bc

通过标准输入,将表达式输入给bc进行运算,如下所示:

  • STDOUT | bc
  • bc < 键盘输入
  • bc << EOF
  • bc < File

表达式由以下部分组成

  • 数值运算(包括浮点数运算)
  • scale=# <=定义小数位数
  • obase=2|8|10|16 <=定义输出几进制的数字
  • ibase=2|8|10|16 <=定义输入几进制的数字

例1,求半径为5的圆的面积

[root@CentOS6 app]# r=5
[root@CentOS6 app]# pi=3.14159
[root@CentOS6 app]# echo "scale=3;$pi*$r*$r" | bc
78.53975

条件测试

在if,while 等流程控制语句中均需使用条件测试表达式的真假来做出流程的选择。

条件测试有以下四种语法:

  • test EXPRESION
  • [ EXPRESION ]
  • [[ EXPRESION ]]
  • ((EXPRESION))

text 和 []
text EXPRESION 等同于 [ EXPRESION ]

EXPRESION 由以下部分组成:

  • 数值比较
    运算符:-gt,-ge,-lt,-le,-eq, -ne
  • 字符串比较
    运算符:/<,/>,=,!=,-z,-n
  • 文件测试
  • 逻辑运算
    运算符:-a,-o,!

[[]]
语法:[[ EXPRESION ]]

EXPRESION 由以下部分组成:

  • 数值比较
    运算符:-gt, -ge, -lt, -le, -eq, -ne
  • 字符串比较
    运算符:< > = != -z -n
  • 文件测试
  • 逻辑运算
    运算符:&& || !
  • 扩展正则表达式
    运算符:=~

(())
主要用来做数值的比较,在if,while语句中使用
语法:((EXPRESION))
EXPRESION 由以下部分组成:

  • 数值比较
    运算符:>, >=, <, <=, ==, !=
  • 逻辑运算
    运算符:&& || !

数值大小比较
适用于: test,[],[[]]

符号 含义
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
-eq 等于
-ne 不等于

字符串比较
适用于: test,[],[[]]

符号 含义
= 等于
!= 不等
>,\> 大于,[]使用 \>,[[]]使用 >
<,\< 小于,[]使用 \<,[[]]使用 <
-n 不空为真
-z 空为真

文件测试
(1) 存在性测试

  • -a file 等同于 -e
  • -e file 文件(所有文件,f,b,c,b,p,s)是否存在,存在为真

(2) 存在性和类别测试

  • -f file : exists and is a file
  • -d file : exist and is dirctory
  • -b file : exists and is block
  • -c file : exists and character
  • -S file : exists and socket
  • -p file : exists and pip
  • -h | -L file : exists and symbolic link

(3) 文件权限测试(针对执行该脚本的用户而言)

  • -r file : exists and readable
  • -w file : exists and writeable
  • -x file : exists and executable

(4) 文件特殊权限测试

  • -u file : exists and SUID
  • -g file : exits and SGID
  • -k file : exists and Sticky

(5) 文件大小测试

  • -s file : 文件存在且不空

(6) 文件是否打开:

  • -N file : 文件自上一次读取之后是否被修改过
  • -O file 当前文件属主是否为当前有效用户
  • -G file 当前文件属组是否为当前有效用户

(7) 双目测试

  • file1 -ef file2 是否为硬链接
  • file1 -nt file2 file1 比 file2 新 (mtime)
  • file1 -ot file2 file2 没有file2 新

实例 1. 判断输入的数字是否为整数

[[ "$var" =~ ^[-]?[0-9]+$ ]]