Shell 运算符
1. Shell 运算符概述
与其他语言一样,Shell 也有运算符,在 Shell 中其根据类型不同也有不少运算符,那么什么是运算符呢?例如大家都知道在算术运算中的加减乘除,+
就是我们 Shell 中的算术运算符的一种,当然还有很多其他的各异的运算符,作为与算术操作等重要,构成了 Shell 中的基本元素。
当我们对数值进行算术运算,当我们需要对进行判断,当我们需要多逻辑进行判断的时候,这些情况都需要使用不同类型的运算符,使得我们脚本更为灵活便捷。
2. Shell 运算符
我们知道了 shell 中运算符是什么及其,接下来让我们看一下 Shell 脚本运算符的及每种运算符的基本操作。
算术运算符顾名思义,其就是进行加减乘除数值运算,在 shell 中,bash 原生的数学运算,需要利用第三方工具来如 let
,expr
等来实现。
可以利用 let
对数值进行运算,let C=$A+$B
, 例如:
[root@master ~]# A=1[root@master ~]# B=2[root@master ~]# let C=${A}+${B}[root@master ~]# echo $C
注意:let
运算后需要将其赋值给变量。
可以利用 expr
对数组进行运算,C=$(expr $A+$B)
,例如:
[root@master ~]# C=`expr $A + $B`[root@master ~]# echo $C
注意 +
号两边需要有空格,不然会将其当作字符串连接
可以利用 []
来对数值进行运算,C=[A+B]
,例如:
[root@master ~]# C=$[$A+$B][root@master ~]# echo $C
利用 (())
来对数值进行运算,C=$(($A+$B))
,例如:
[root@master ~]# C=$(($A+$B))[root@master ~]# echo $C
了解了算术运算,接下来让我们学习关系运算。
关系运算顾名思义就是比较数字的大小,注意关系运算符作用的为数字,不能用其来比较字符串。
#!/bin/bashnum1=num2=echo "num1 为:${num1}"echo "num2 为:${num2}"if [ $num1 -eq $num2 ]then echo "$num1 -eq $num2 : num1 等于 num2"else echo "$num1 -eq $num2: num1 不等于 num2"fiif [ $num1 -ne $num2 ]then echo "$num1 -ne $num2: num1 不等于 num2"else echo "$num1 -ne $num2 : num1 等于 num2"fiif [ $num1 -gt $num2 ]then echo "$num1 -gt $num2: num1 大于 num2"else echo "$num1 -gt $num2: num1 不大于 num2"fiif [ $num1 -lt $num2 ]then echo "$num1 -lt $num2: num1 小于 num2"else echo "$num1 -lt $num2: num1 不小于 num2"fiif [ $num1 -ge $num2 ]then echo "$num1 -ge $num2: num1 大于或等于 num2"else echo "$num1 -ge $num2: num1 小于 num2"fiif [ $num1 -le $num2 ]then echo "$num1 -le $num2: num1 小于或等于 num2"else echo "$num1 -le $num2: num1 大于 num2"fi
运行结果为:
num1 为: num2 为: -eq : num1 不等于 num2 -ne : num1 不等于 num2 -gt : num1 不大于 num2 -lt : num1 小于 num2 -ge : num1 小于 num2 -le : num1 小于或等于 num2
布尔运算符也就是我们常说的与或非
例如:
#!/bin/bashnum1=num2=echo "num1 为: ${num1}"echo "num2 为: ${num2}"if [ $num1 -lt - $num2 -gt ];then echo "$num1 小于 40 且 $num2 大于 15 : 返回 true"else echo "$num1 小于 40 且 $num2 大于 15 : 返回 fnum1lse"fi echo "或运算"if [ $num1 -lt -o $num2 -gt ];then echo "$num1 小于 40 或 $num2 大于 40 : 返回 true"else echo "$num1 小于 40 或 $num2 大于 40 : 返回 fnum1lse"fi echo "非运算"if [ $num1 != $num2 ];then echo "$num1 != $num2 : num1 不等于 num2"else echo "$num1 != $num2: num1 等于 num2"fi
返回结果为:
num1 为: num2 为: 小于 且 大于 : 返回 true或运算 小于 或 大于 : 返回 true非运算 != : num1 不等于 num2[root@master scripts]# vim 2.sh [root@master scripts]# bash 2.sh num1 为: num2 为: 小于 且 大于 : 返回 true或运算 小于 或 大于 : 返回 true非运算 != : num1 不等于 num2
逻辑运算符为,以下介绍 Shell 的逻辑运算符,假定变量 A 为 1,变量 b 为 2:
例如:
#!/bin/bashnum1=num2=echo "num1 为:${num1}"echo "num2 为:${num2}"if [[ $num1 -lt && $num2 -gt ]];then echo "返回 true"else echo "返回 false"fiif [[ $num1 -lt || $num2 -gt ]];then echo "返回 true"else echo "返回 false"fi
返回:
num1 为: num2 为: 返回 false返回 true
对于字符串进行一些判断操作,假定变量 a 为 “linux”,变量 b 为 “shell”:
例如:
#!/bin/bashstr1="linux"str2="shell"echo "str1 为:${str1}"echo "str2 为:${str2}"if [ $str1 = $str2 ];then echo "$str1 = $str2 : str1 等于 str2"else echo "$str1 = $str2: str1 不等于 str2"fiif [ $str1 != $str2 ];then echo "$str1 != $str2 : str1 不等于 str2"else echo "$str1 != $str2: str1 等于 str2"fiif [ -z $str1 ];then echo "-z $str1 : 字符串长度为 0"else echo "-z $str1 : 字符串长度不为 0"fiif [ -n "$str1" ];then echo "-n $str1 : 字符串长度不为 0"else echo "-n $str1 : 字符串长度为 0"fiif [ ${str1} ];then echo "str1 : 字符串不为空"else echo "str1 : 字符串为空"fi
返回为:
str1 为:linux str2 为:shell linux = shell: str1 不等于 str2 linux != shell : str1 不等于 str2-z linux : 字符串长度不为 -n linux : 字符串长度不为 str1 : 字符串不为空
测试在我们编写 shell 中与操作非常常用,熟练掌握操作可以在后续的 shell 编写中得心应手,例如 file 变量为:
例如:
#!/bin/bash TEST_FILE="/etc/fstab" echo "检测的为:${TEST_FILE}" echo "信息为:$(ls -l ${TEST_FILE})" if [ -r $TEST_FILE ] then echo "可读" else echo "不可读" fi if [ -w $TEST_FILE ] then echo "可写" else echo "不可写" fi if [ -x $TEST_FILE ] then echo "可执行" else echo "不可执行" fi if [ -f $TEST_FILE ] then echo "为普通" else echo "为特殊" fi if [ -d $TEST_FILE ] then echo "是个目录" else echo "不是个目录" fi if [ -s $TEST_FILE ] then echo "不为空" else echo "为空" fi if [ -e $TEST_FILE ] then echo "存在" else echo "不存在" fi
返回为:
检测的为:/etc/fstab 信息为:-rw-r--r--. 1 root root 500 Jan 17 14:23 /etc/fstab 可读 可写 不可执行 为普通 不是个目录 不为空 存在
3. 实例
编写脚本,传入 linux 系统的路径,判断其下面及目录的。
可以利用测试运算符来判断的目录是否正确,之后利用算术运算符配合数组对或目录进行。
#!/bin/bash# Description: count file scripts# Auth: kaliarch# Email: kaliarch@163.com# function: count file# Date: 2020-03-08 14:00# Version: 1.0# 判断输入参数[ $# -ne 1 ] && echo "输入参数,${0} check_dir" && exit 1# 判断输入的是否为存在的目录,不存在则CHECK_DIR=$1[ ! -d ${CHECK_DIR} ] && echo "检测系统不存在目录:${CHECK_DIR}, 请输入正确的目录" && exit 1# 对目录下的进行DIR_NUM=0 FILE_NUM=0 OTHER_NUM=0for item in ${CHECK_DIR}/*doif [ -d ${item} ];then# 如果为目录,则目录总数加一DIR_NUM=$((${DIR_NUM}+))elif [ -f ${item} ];thenFILE_NUM=$((${FILE_NUM}+))elTHER_NUM=$((${OTHER_NUM}+))fidoneecho "检测目录为:${CHECK_DIR}"echo "类型为:${FILE_NUM}"echo "目录类型为:${DIR_NUM}"echo "其他类型为:${OTHER_NUM}"[root@master scripts]# bash count_file.sh 输入参数,count_file.sh check_dir[root@master scripts]# bash count_file.sh aaaa检测系统不存在目录:aaaa, 请输入正确的目录[root@master scripts]# bash count_file.sh /tmptmptmp检测系统不存在目录:/tmptmptmp, 请输入正确的目录[root@master scripts]# bash count_file.sh /检测目录为:/ 类型为:0 目录类型为:23 其他类型为:0[root@master scripts]# bash count_file.sh /root检测目录为:/root 类型为:8 目录类型为:5 其他类型为:0[root@master scripts]# bash count_file.sh /dev/检测目录为:/dev/ 类型为:1 目录类型为:19 其他类型为:139
当我们不输入任何参数的时候,需要输入路径参数,输入了或不存在的路径时,测试运算符判断输入异常,不是有效的目录。
当我们输入正常的目录时,即可获得正确的目录或数。
4. 注意事项
对于算术运算,大家可以根据具体场景和环境来选择,例如系统内没有计算工具等,可以优先选择 []
和 (())
来进行,也可以根据自己喜好选择;
对于关系运算,比较的数字,不是字符串,一定要牢记这个注意点,对于字符串判断可以用字符串运算符;
对于布尔运算和逻辑运算其实是东西,只不过布尔运算符有非运算,可以进行灵活运用;
测试符常用与判断 linux 系统的操作,在后期 shell 编程可谓举足轻重,牢记每个运算符会使得后期编程得心应手。
5. 小结
运算符可谓 Shell 脚本的灵魂,后期我们的循环和判断里面的条件都是这些运算符构成,它是流程框架的基础,熟练掌握运算符的及每个的,通过动手实践区分其特征,举一反三灵活运用。