shell基础 元字符

元字符

元字符指的是能够被shell解释的特殊字符,每个特殊字符都有其特殊含义,这些字符一方面可用于变量值的运算、我们可以称之为运算符,另外一方面可以和shell命令配合使用来达到更高级的效果

算数运算符

算数运算符需要配合下述操作使用

# 浮点运算
bc  

# 整数运算
expr
$(())
$[]
let

bc是比较常用的linux计算工具了,而且支持浮点运算

[root@m01 ~]# res=`echo 1+1 | bc`				
[root@m01 ~]# echo $res
2
[root@m01 ~]# res=`echo 10 % 3| bc`				% 取余数		
[root@m01 ~]# echo $res
1
[root@m01 ~]# res=`echo 1.2+1.3|bc`
[root@m01 ~]# echo $res
2.5
[root@m01 ~]# res=`echo 5.0+3.0|bc`
[root@m01 ~]# echo $res
8.0
[root@m01 ~]# res=`echo "scale=2;5.0/3.0"|bc`			/ 除(取相除后的值,scale=2保留两位小数)
[root@m01 ~]# echo $res
1.66
[root@m01 ~]# res=`echo "scale=3;5.0/6.0"|bc`			/ 除(取相除后的值,scale=3保留三位小数)
[root@m01 ~]# echo $res
.833

expr不支持浮点数计算,而且要注意数字与运算符中的空格

[root@m01 ~]# res=`expr 5 / 3`				# 不支持浮点计算
[root@m01 ~]# echo $res
1
[root@m01 ~]# res=`expr 1+1`			  # 注意:要有空格
[root@m01 ~]# echo $res
1+1
[root@m01 ~]# res=`expr 1 + 1`
[root@m01 ~]# echo $res
2

如果是乘法,需要转义\*
[root@m01 ~]# expr 3 \* 10
30

$(( )) 同expr,不支持浮点数运算

[root@m01 ~]# echo $((1+1))
2
[root@m01 ~]# echo $((1.0+1.0))				$(())不支持浮点数运算
-bash: 1.0+1.0: syntax error: invalid arithmetic operator (error token is ".0+1.0")

# 注意:
echo $(($num1+$num2))  # 也可以简写为 echo $((num1+num2)) 
echo $(((5-3)*2))  # 可以嵌套括号     

let 不支持浮点数运算,而且不支持直接输出,只能赋值

[root@m01 ~]# let res=1+1
[root@m01 ~]# echo $res
2
[root@m01 ~]# let res=10/2
[root@m01 ~]# echo $res
5
[root@m01 ~]# let c=1.3*3
-bash: let: c=1.3*3: syntax error: invalid arithmetic operator (error token is ".3*3")

算数运算符练习题

计算器,可实现加减乘除
vim test.sh
#!/bin/bash

read -p "输入数字" num1
read -p "输入运算符" symbol
read -p "输入数字" num2

NUM=`echo $num1 $symbol $num2 | bc`
echo $NUM
实现2位数加减乘除运算
vim a.sh
#!/bin/bash

a=$1
b=$2

# $#输入参数的个数 , -ne不等于
[ $# -ne 2 ] && {			
        echo "请输入两位数字信息"
        exit
}

echo "a-b=$(($a-$b))"
echo "a+b=$(($a+$b))"
echo "a*b=$(($a*$b))"
echo "a/b=$(($a/$b))"
编写判断输入参数是否是整数信息
vim test01.sh
#!/bin/bash

a=$1
# 只有整型加0才不会报错,浮点数及字符与0相加都会报错
expr $a + 0 &> /dev/null		
[ $? -eq 0 ] && echo "输入的是整数信息" || echo "输入的是非整数信息"
如何利用脚本计算1+2+3+4..10总和数值
python写法
a = 0
b = 1
while True:
    if b <= 10:
        a = a + b
        b = b + 1
    else:
        print(a)
        break
如何利用脚本计算1+2+3+4..10总和数值
shell写法
方法一:
seq -s "+" 10|bc
[root@m01 ~]# seq -s "+" 10
1+2+3+4+5+6+7+8+9+10 

方法二:
echo {1..10}|tr " " "+"|bc
[root@m01 ~]# echo {1..10}|tr " " "+"
1+2+3+4+5+6+7+8+9+10

方法三:
awk 'BEGIN{for (i=1; i<=10; i++) a=a+i; print a}'

测试运算符

测试命令:test,详细可用man test查询

测试符号:[ ],注意只有一层中括号,中括号内左右两侧必须要有空格

test与[]效果都一样,参数也都一样

测试文件状态

-d 判断是否是目录
[root@m01 ~]# test -d /etc/;echo $?
0
[root@m01 ~]# [ -d /etc/ ];echo $? 		 # 注意[]内左右两侧要有空格
0

-s 判断文件内容长度>0、非空
[root@m01 ~]# echo 123 > a.txt
[root@m01 ~]# test -s a.txt;echo $?
0
[root@m01 ~]# [ -s a.txt ];echo $?
0

-f 判断文件属性标准文件
[root@m01 ~]# test -f /etc/passwd;echo $?
0
[root@m01 ~]# [ -f /etc/passwd ];echo $?
0

-w 可写
[root@m01 ~]# chmod a-w a.txt
[root@m01 ~]# su - nana
[nana@m01 ~]$ [ -w a.txt ];echo $?			# 返回假,注意,如果是root用户,无论如何都有写权限
1
[nana@m01 ~]$ test -w a.txt;echo $?
1

-r 可读
[root@m01 ~]# ll a.txt
-r--r--r-- 1 root root 4 Jun 17 15:11 a.txt
[root@m01 ~]# test -r a.txt;echo $?
0
[root@m01 ~]# [ -r a.txt ];echo $?
0

-x 可执行
[root@m01 ~]# ll a.txt
-r--r--r-- 1 root root 4 Jun 17 15:11 a.txt
[root@m01 ~]# test -x a.txt;echo $?
1
[root@m01 ~]# [ -x a.txt ];echo $?
1

-L 符号连接(判断是否是软链接)
[root@m01 ~]# ll -d /lib
lrwxrwxrwx. 1 root root 7 Apr 19 23:46 /lib -> usr/lib
[root@m01 ~]# [ -L /lib ];echo $?
0
[root@m01 ~]# test -L /lib;echo $?
0

-u 文件有suid位设置(ACL权限设置)
[root@m01 ~]# ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 27856 Apr  1  2020 /usr/bin/passwd
[root@m01 ~]# [ -u /usr/bin/passwd ];echo $?
0
[root@m01 ~]# test -u /usr/bin/passwd;echo $?
0

-c 判断是否是磁盘文件
[root@m01 ~]# test -c /dev/null;echo $?
0
[root@m01 ~]# [ -c /dev/null ];echo $?
0

字符串测试

== 两个字符串相等
[root@m01 ~]# [ "AAA" == "AAA" ];echo $?
0

!= 两个字符不相等
[root@m01 ~]# [ "AAA" != "AAA" ];echo $?
1

-z 字符长度为零
[root@m01 ~]# ip=" "
[root@m01 ~]# [ -z "$ip" ];echo $?				# 注意引号
0
[root@m01 ~]# ip="1.1.1.1"
[root@m01 ~]# test -z "$ip";echo $?
1

-n 字符串长度不为零
[root@m01 ~]# a=
[root@m01 ~]# [ -n "$a" ];echo $?			# 注意加引号
1

测试数值

test与[ ]也可以测试数值,与 [[ ]]和(( ))效果一样

  • -eq 等于
  • -ne 不等于
  • -gt 大于
  • -lt 小于
  • -ge 大于等于
  • -le 小于等于
  • -a 并且
  • -o 或者
[root@m01 ~]# [ 10 -eq 10 ];echo $?
0
[root@m01 ~]# [ 10 -eq 10 -a 10 > 3 ];echo $?
0

示例1
[root@m01 ~]# disk_use=`df -P | grep "/boot$" | awk '{print $5}' | awk -F% '{print $1}'`
[root@m01 ~]# echo disk_use
disk_use
[root@m01 ~]# echo $disk_use
14
[root@m01 ~]# [ $disk_use -gt 10 ] && echo "warn..."
warn...

示例2
[root@m01 ~]# [ $(id -u) -eq 0 ] && echo "当前是超级用户" || echo "you不是超级用户"
当前是超级用户

关系运算符

  <
  >
  <=
  >=
  ==
  !=
  &&
  ||
  上述关系运算符需要配合(( ))使用(注意(( ))属于C语言风格的比较),最终都是用来当if判断或者while循环的条件
[root@m01 ~]# x=100
[root@m01 ~]# (($x > 10));echo $?
0
[root@m01 ~]# (($x < 10));echo $?
1
[root@m01 ~]# (($x == 100));echo $?
0
[root@m01 ~]# (($x != 100));echo $?
1
[root@m01 ~]# (($x != 100)) || (("nana" == "nana"))
[root@m01 ~]# echo $?
0
[root@m01 ~]# (($x != 100)) && (("lala" == "lala"))
[root@m01 ~]# echo $?
1
[root@m01 ~]# (($x != 100 || "nana" == "nana"))
[root@m01 ~]# echo $?
0
[root@m01 ~]# (($x != 100 && "nana" == "nana"))
[root@m01 ~]# echo $?
1

赋值运算符

=
[root@m01 ~]# x=10
[root@m01 ~]# echo $x
10

+=
[root@m01 ~]# x=10
[root@m01 ~]# ((x+=10))
[root@m01 ~]# echo $x
20

*=
[root@m01 ~]# x=10
[root@m01 ~]# ((x*=2))
[root@m01 ~]# echo $x
20

/=
[root@m01 ~]# x=10
[root@m01 ~]# ((x/=2))
[root@m01 ~]# echo $x
5

%=
[root@m01 ~]# x=10
[root@m01 ~]# ((x%=3))
[root@m01 ~]# echo $x
1

[[ ]]

[[ ]]与[ ]基本一样,不同的是[[ ]]支持正则匹配,不过要注意的是必须在内层中括号内左右两侧加空格

[root@m01 ~]# user=root
[root@m01 ~]# [[ "$user" == "root" ]];echo $?				# 注意内层[]中包含的内容必须左右两侧加空格
0	
[root@m01 ~]# [[ "$user" = "root" ]];echo $?				# 一个等号也行两个等号也可以
0

此外[[ ]]内部是可以使用正则的,注意:正则表达式不要加引号
[root@m01 ~]# [[ "$user" =~ "^root$" ]];echo $?	 		 # 正则表达式不要加引号	
1
[root@m01 ~]# [[ "$user" =~ ^root$ ]];echo $?			# 正则表达式不要加引号
0
[root@m01 ~]# [[ ! "$user" =~ ^root$ ]] && echo 此时登陆的不是管理员 || echo 是管理员啊
是管理员啊

[root@m01 ~]# num1=123
[root@m01 ~]# [[ "$num1" =~ ^[0-9]+$ ]];echo $?
0
[root@m01 ~]# [[ "$num1" =~ ^[0-9]+$ ]];echo "数字"
数字
传入两个数值信息, 自动让脚本显示数值比较情况
- 整数比较
vim num.sh
#!/bin/bash

[ $# -ne 2 ] && echo "只能传入两个整数" && exit

[[ ! $1 =~ ^[0-9]+$ ]] && echo "参数1必须是整数" && exit
[[ ! $2 =~ ^[0-9]+$ ]] && echo "参数2必须是整数" && exit

方式一:
# [[ $1 -lt $2 ]] && echo "$1 < $2"
# [[ $1 -gt $2 ]] && echo "$1 > $2"
# [[ $1 -eq $2 ]] && echo "$1 = $2"

方式二:
(( $1 < $2 )) && echo "$1 < $2"
(( $1 > $2 )) && echo "$1 > $2"
(( $1 == $2 )) && echo "$1 = $2"

- 浮点数的比较		# 需要注意的是: bc的结果为1代表真,为0代表假
[root@m01 ~]# echo "10.3 >= 10.1" | bc
1
[root@m01 ~]# echo "10.3 != 10.1" | bc
1
[root@m01 ~]# x=10.3
[root@m01 ~]# y=10.1
[root@m01 ~]# [ `echo "$x >= $y" | bc` -eq 1 ]&& echo "$x > $y"			需要注意的是: bc的结果为1代表真,为0代表假
10.3 > 10.1

[root@m01 ~]# (( `echo "$x >= $y" | bc` == 1 ))&& echo "$x > $y"		需要注意的是: bc的结果为1代表真,为0代表假
10.3 > 10.1

其他元字符

> 1、`` 与$()  取命令的结果 
> 2、~家目录 
> 3、... 
> 4、!调用历史命令、取反 
> 5、@无特殊意义 
> 6、#注释 
> 7、$取变量值
> 8、%-+运算符,注意%可以与jobs配合“kill %工作号”杀后台进程。-减号还有区间及cd -回到上一级的意思
> 9、^同!一样
> 10、&后台运行
> 11、*任意多个字符
> 12、()在子shell中执行
> 13、_下划线:无特殊意义,可以用于名字的声明
> 14、=赋值,==判断相等性
> 15、|管道:把一个进程的处理结果传递给另外一个进程
> 16、\转义特殊字符
> 17、[]条件测试
> 18、 ''  强引用(在单引号中都视为普通字符)		" " 弱引用 (在双引号中保留变量)
> 19、;与&&与||连接多条命令
> 20、:空命令,真值
> 21、/路径分隔符
> 22、{}循环列表
> 23、>    >> 输出重定向			<     << 输入重定向
> 24、?任意一个字符
> 25、范围中的任意一个字符  ls a[A-Z]c  # 不区分大小写		ls a[0-9]c
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值