一、元字符
元字符指的是能够被shell解释的特殊字符,每个特殊字符都有其特殊含义,这些字符一方面可用于变量值的运算、我们可以称之为运算符,另外一方面可以和shell命令配合使用来达到更高级的效果
算数运算符
运算符
- +
- -
- *
- /
- %
算数运算符需要配合下述操作使用
# 浮点运算
bc
# 整数运算
expr
$(())
$[]
let
- 整数运算示例
[root@localhost test]# a=1
[root@localhost test]# b=2
[root@localhost test]# expr $a + $b
3
[root@localhost test]# echo $((1+2))
3
[root@localhost test]# echo $(( $a + $b ))
3
[root@localhost test]# echo $[ $a + $b ]
3
- 补充expr乘法运算
[root@localhost test]# expr 1 * 3
expr: 语法错误
[root@localhost test]# expr 1 \* 3
3
- 浮点运算:bc
[root@localhost test]# yum install -y bc
[root@localhost test]# echo "scale=2;3/10" |bc
.30
[root@localhost test]# echo "scale=2;10/3" |bc
3.33
[root@localhost test]# x=` echo "scale=2;3/10" |bc`
[root@localhost test]# echo $x
.30
[root@localhost test]# echo 0$x
0.30
补充:清理buffer、cache的命令
sync
echo 3 >/proc/sys/vm/drop_caches
[root@localhost test]# free -w
total used free shared buffers cache available
Mem: 995672 182740 523736 7172 2116 287080 611840
Swap: 1048572 0 1048572
[root@localhost test]# sync
[root@localhost test]# echo 3 >/proc/sys/vm/drop_caches
二、测试运算符–》man test手册
2.1文件状态测试
- -d:目录
[root@localhost test]# test -d /etc/
[root@localhost test]# echo $?
0
[root@localhost test]# [ -d /etc ]
[root@localhost test]# echo $?
0
[root@localhost test]# [ -d /etc/passwd ]
[root@localhost test]# echo $?
1
- -s :文件长度大于0
[root@localhost test]# [ -s /etc/passwd ];echo $?
0
[root@localhost test]# touch a.txt
[root@localhost test]# [ -s a.txt ]; echo $?
1
- -f/w/r/x/
[root@localhost test]# [ -f a.txt ];echo $?
0
[root@localhost test]# ll a.txt
-rw-r--r--. 1 root root 0 3月 5 07:17 a.txt
[root@localhost test]# [ -w a.txt ];echo $?
0
[root@localhost test]# [ -r a.txt ];echo $?
0
[root@localhost test]# [ -x a.txt ];echo $?
1
- -L: 是否有连接
[root@localhost test]# ln -s a.txt b.txt
[root@localhost test]# ll a.txt
-rw-r--r--. 1 root root 0 3月 5 07:17 a.txt
[root@localhost test]# ll b.txt
lrwxrwxrwx. 1 root root 5 3月 5 07:28 b.txt -> a.txt
[root@localhost test]# [ -L a.txt ];echo $?
1
[root@localhost test]# [ -L b.txt ];echo $?
0
2.2字符串测试(细节必须[]号内加上引号)
- -n:代表长度非零
[root@localhost test]# a=""
[root@localhost test]# echo ${#a}
0
[root@localhost test]# b="123abc"
[root@localhost test]# [ -n ]
[root@localhost test]# [ -n "$a" ];echo $?
1
[root@localhost test]# [ -n "$b" ];echo $?
0
- -z 字符串长度为零
[root@egon ~]# ip=""
[root@egon ~]# [ -z "$ip" ];echo $? # 注意引号
0
[root@egon ~]# ip='1.1.1.1'
[root@egon ~]# [ -z "$ip" ];echo $?
1
- =:代表相等
[root@localhost test]# [ "123abc" = "123abc" ];echo $?
0
[root@localhost test]# a=123abc
[root@localhost test]# b=123abc
[root@localhost test]# [ "$a" = "$b" ];echo $?
0
[root@localhost test]# expr length "$a"
6
[root@localhost test]# echo "$a" | wc -L
6
[root@localhost test]# echo "$a" | awk '{print length}'
6
[root@localhost test]# echo ${#a}
6
- !=:代表字符串不相等
[root@localhost test]# [ "abc" != "ddd" ];echo $?
0
[root@localhost test]# [ "abc" != "abc" ];echo $?
1
三、测试数值
-
-eq 等于
-
-ne 不等于
-
-gt 大于
-
-lt 小于
-
-ge 大于等于
-
-le 小于等于
-
-a并且
-
-o或者
示例
[root@localhost ~]# man test
[root@localhost ~]# [ 10 -eq 10 ];echo $?
0
[root@localhost ~]# [ 10 -gt 10 ];echo $?
1
[root@localhost ~]# [ 10 -lt 10 ];echo $?
1
[root@localhost ~]# [ 10 -lt 11 ];echo $?
0
[root@localhost ~]# [ 10 -ge 11 ];echo $?
1
[root@localhost ~]# [ 10 -ge 8 ];echo $?
0
[root@localhost ~]# [ 10 -le 8 ];echo $?
1
[root@localhost ~]# [ 10 -le 11 ];echo $?
0
[root@localhost ~]# [ 10 -ne 11 ];echo $?
0
[root@localhost ~]# [ 10 -ne 10 ];echo $?
1
[root@localhost ~]# [ 10 -gt 5 ] && [ 3 -le 3 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 10 -gt 5 -a 3 -le 3 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 10 -gt 30 ] || [ 3 -le 2 ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ 10 -gt 30 ] || [ 3 -le 3 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 10 -gt 30 -o 3 -le 3 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# read -p "username: " inp_name
username: yuan
[root@localhost ~]# read -p "password: " inp_pwd
password: 123
[root@localhost ~]# [ "$inp_name" = "yuan" -a "$inp_pwd" = 123 ];echo $?
0
四、关系运算符
- <
- >
- <=
- >=
- ==
- !=
- &&
- ||
- 相当于 C语言的风格
示例
[root@localhost ~]# (( 10 >= 3 ));echo $?
0
[root@localhost ~]# (( 10 < 3 ));echo $?
1
[root@localhost ~]# (( 10 == 3 ));echo $?
1
[root@localhost ~]# (( 10 == 10 ));echo $?
0
[root@localhost ~]# (( 10 != 10 ));echo $?
1
[root@localhost ~]# (( 10 != 10 )) && ((10 > 7 ))
[root@localhost ~]# echo $?
1
[root@localhost ~]# (( 10 != 10 )) || ((10 > 7 ))
[root@localhost ~]# echo $?
0
五、赋值运算符
- =
- +=
- *=
- /=
- %= 取余数
[root@localhost ~]# age=10
[root@localhost ~]# age=`expr $age + 10`
[root@localhost ~]# echo $age
20
[root@localhost ~]# ((age+=10))
[root@localhost ~]# echo $age
30
[root@localhost ~]# ((age-=10))
[root@localhost ~]# echo $age
20
[root@localhost ~]# ((age*=10))
[root@localhost ~]# echo $age
200
[root@localhost ~]# x=10
[root@localhost ~]# ((x%=3))
[root@localhost ~]# echo $x
1
六、补充
6.1[]与[[]]
[[]]与[]基本一样,不同的是[[]]支持正则匹配,不过要注意的是必须在内层中括号内左右两侧加空格
示例–>与[]一样
[root@localhost ~]# su - yuan
[yuan@localhost ~]$
[yuan@localhost ~]$ [[ "abc" = "abc" ]]
[yuan@localhost ~]$ echo $?
0
示例---->支持正则表达式
[yuan@localhost ~]$ echo $USER
yuan
[yuan@localhost ~]$ [[ $USER =~ ^ro ]]
[yuan@localhost ~]$ echo $?
1
[yuan@localhost ~]$ su -
密码:
上一次登录:五 3月 5 08:46:48 CST 2021从 10.0.0.1pts/3 上
[root@localhost ~]# [[ "$USER" =~ ^ro ]]
[root@localhost ~]# echo $?
0
示例–>整数
#!/bin/bash
[ $# -ne 1 ] && echo "请传输一个参数" && exit
[[ ! $1 =~ ^[0-9]+$ ]] && echo "参数必须为数字" && exit
echo "========ok"
~
有小数点
#!/bin/bash
[ $# -ne 1 ] && echo "请传输一个参数" && exit
[[ ! $1 =~ ^[0-9]+(\.[0-9]+)?$ ]] && echo "参数必须为数字" && exit
echo "ok---->$1"
企业面试题1: 传入两个数值信息, 自动让脚本显示数值比较情况
#!/bin/bash
#第一道关卡
[ $# -ne 2 ] && echo "uasge :$0 arg1 arg2" && exit
#第二道关卡
[[ ! $1 =~ ^[0-9]+$ ]] && echo " 请输入整数" && exit
#第三道关卡
[[ ! $2 =~ ^[0-9]+$ ]] && echo " 请输入整数" && exit
[ $1 -gt $2 ] && echo "第一个数大"
[ $1 -lt $2 ] && echo "第二个数大"
[ $1 -eq $2 ] && echo " 两个数一样大"
七、 补充浮点数的比较
需要注意的是bc正确处理的结果为1,反之为0
[root@localhost ~]# echo "13.33 > 5.5" |bc
1
[root@localhost ~]# echo "13.33 > 33" |bc
0
[root@localhost ~]# echo "20 > 10" |bc
1
[root@localhost ~]# echo "20 > 50" |bc
0
[root@localhost ~]# echo "10.5 > 3.8" |bc
1
[root@localhost ~]# res=`echo "10.5 > 3.8" |bc`
[root@localhost ~]# [ $res -eq 1 ] && echo "第一个数大"
第一个数大
[root@localhost ~]# echo "10.44 == 10.44" |bc
1
[root@localhost ~]# echo "10.44 != 10.44" |bc
0
八、总结
条件测试:
格式1: test 条件表达式
格式2: [ 条件表达式 ]
格式3: (()) 数值比较,运算 C语言
格式4: [[ 条件表达式 ]],支持正则 =~
结合$符号
$[] # 整数运算
$(()) # 整数运算
$() # 与反引号类似取结果``
九、 其他元字符
1、`` 与$():取命令的结果
[root@localhost ~]# echo `pwd`
/root
[root@localhost ~]# echo $(pwd)
/root
不一样的地方在于$()可以嵌套,而``不能嵌套
[root@localhost ~]# echo $(ls $(pwd))
# 练习
[root@aliyun test]# touch $(date +%F)_bak.tar.gz
[root@aliyun test]# ls
2020-08-24_bak.tar.gz
-
2、~家目录
-
3、.与…
-
4、!调用历史命令、取反
[root@localhost ~]# touch {a,b,c}.txt
[root@localhost ~]# ls
anaconda-ks.cfg a.sh a.txt b.sh b.txt c.sh c.txt f.sh g.sh login.sh ping.sh test txt
[root@localhost ~]# touch {1..9}.txt
[root@localhost ~]# ls
1.txt 3.txt 5.txt 7.txt 9.txt a.sh b.sh c.sh f.sh login.sh test
2.txt 4.txt 6.txt 8.txt anaconda-ks.cfg a.txt b.txt c.txt g.sh ping.sh txt
[root@localhost ~]# ls *.txt
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt a.txt b.txt c.txt
[root@localhost ~]# ls [0-9].txt
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
[root@localhost ~]# ls [!0-9].txt
a.txt b.txt c.txt
[root@localhost ~]# ls [^0-9].txt
a.txt b.txt c.txt
-
5、@无特殊意义
-
6、#注释
-
4、$取变量值
[root@localhost ~]# x=1
[root@localhost ~]# echo $x
1
- 5、%、-、+运算符,注意%可以与jobs配合“kill %工作号”杀后台进程。-减号还有区间及cd -回到上一级的意思
# 数学运算
# 1、bc是比较常用的linux计算工具了,而且支持浮点运算:
[root@localhost ~]# res=`echo 1+1 | bc`
[root@localhost ~]# echo $res
2
[root@localhost ~]# res=`echo 10 % 3 | bc`
[root@localhost ~]# echo $res
1
[root@localhost ~]# res=`echo 1.2+1.3|bc`
[root@localhost ~]# echo $res
2.5
[root@localhost ~]# res=`echo 5.0+3.0|bc`
[root@localhost ~]# echo $res
8.0
[root@localhost ~]# res=`echo "scale=2;5.0/3.0"|bc`
[root@localhost ~]# echo $res
1.66
[root@localhost ~]# res=`echo "scale=2;5.0/6.0"|bc`
[root@localhost ~]# echo $res
.83
# 2、expr不支持浮点数计算。而且要注意数字与运算符中的空格
[root@localhost ~]# res=`expr 5 / 3` # 不支持浮点计算
[root@localhost ~]# echo $res
1
[root@localhost ~]# res=`expr 1+1` # 注意:要有空格
[root@localhost ~]# echo $res
1+1
[root@localhost ~]# res=`expr 1 + 1`
[root@localhost ~]# echo $res
2
[root@localhost ~]# res=`expr 5 \* 3` # 在expr中*号要转义才能用,否则报语法错误
[root@egon ~]# echo $res
15
# 3、$(()) 同expr,不支持浮点数运算
[root@localhost ~]# echo $((1+1))
2
[root@localhost ~]# echo $((1.0+2.0))
-bash: 1.0+2.0: 语法错误: 无效的算术运算符 (错误符号是 ".0+2.0")
# 4、$[]同expr以及$(()),不支持浮点运算
[root@localhost ~]# x=1
[root@localhost ~]# echo $[$x+1]
2
# 5、let 不支持浮点数运算,而且不支持直接输出,只能赋值
[root@localhost ~]# let res=1+1
[root@localhost ~]# echo $res
2
[root@localhost ~]#
[root@localhost ~]# let res=50/5
[root@localhost ~]# echo $res
10
[root@localhost ~]# let c=1.3*3
-bash: let: c=1.3*3: 语法错误: 无效的算术运算符 (错误符号是 ".3*3"
[root@aliyun test]# x=1
[root@aliyun test]# let x+=10
[root@aliyun test]# echo $x
11
jobs
[root@localhost ~]# sleep 10000
^Z
[1]+ 已停止 sleep 10000
[root@localhost ~]# jobs
[1]+ 已停止 sleep 10000
[root@localhost ~]# sleep 30000
^Z
[2]+ 已停止 sleep 30000
[root@localhost ~]# jobs
[1]- 已停止 sleep 10000
[2]+ 已停止 sleep 30000
[root@localhost ~]# kill %1
[1]- 已停止 sleep 10000
[root@localhost ~]# joobs
-bash: joobs: 未找到命令
[1]- 已终止 sleep 10000
[root@localhost ~]# jobs
[2]+ 已停止 sleep 30000
[root@localhost ~]# fg %1
-bash: fg: %1: 无此任务
[root@localhost ~]# fg %2
sleep 30000
-
6、^同!一样
-
7、&后台运行
[root@localhost ~]# ping -c 1 10.0.0.2 &
[3] 35947
ping网关通不通的脚本
#!/bin/bash
ip1="10.0.0.1"
ip2="10.0.0.2"
ip3="10.0.0.3"
ip4="10.0.0.4"
ip5="10.0.0.5"
(ping -c 1 $ip1 &>/dev/null
[ $? -eq 0 ] && echo "$ip1 is ok" || echo "$ip1 is down"
) &
(ping -c 1 $ip2 &>/dev/null
[ $? -eq 0 ] && echo "$ip2 is ok" || echo "$ip2 is down")&
(ping -c 1 $ip3 &>/dev/null
[ $? -eq 0 ] && echo "$ip3 is ok" || echo "$ip3 is down") &
(ping -c 1 $ip4 &>/dev/null
[ $? -eq 0 ] && echo "$ip4 is ok" || echo "$ip4 is down") &
(ping -c 1 $ip5 &>/dev/null
[ $? -eq 0 ] && echo "$ip5 is ok" || echo "$ip5 is down") &
- 8、*任意多个字符
[root@localhost ~]# touch {1..9}.txt
[root@localhost ~]# ls
1.txt 3.txt 5.txt 7.txt 9.txt a.sh b.sh c.sh f.sh login.sh test
2.txt 4.txt 6.txt 8.txt anaconda-ks.cfg a.txt b.txt c.txt g.sh ping.sh txt
[root@localhost ~]# ls *.txt
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt a.txt b.txt c.txt
-
9、()在子shell中执行
-
10、_下划线:无特殊意义,可以用于名字的声明
-
11、=赋值,==判断相等性
[root@localhost ~]# [ 1 == 1 ] # 条件1 == 1的左右两边必须有空格
[root@localhost ~]# echo $? # 判断上一条命令的结果是否为真,0=》true
0
- 12、|管道:把一个进程的处理结果传递给另外一个进程
- 转义特殊字符
[root@localhost ~]# echo $RMB # 默认会当成变量
[root@localhost ~]# echo '$RMB' # 取消特殊意义
$RMB
[root@localhost ~]# echo \$RMB # 取消特殊意义
$RMB
- 14、[]条件测试,后续会详细介绍
[root@localhost ~]# name="egon"
[root@localhost ~]# [ $name == "egon" ];echo $?
0
[root@localhost ~]# name="adf"
[root@localhost ~]# [ $name == "egon" ];echo $?
1
[root@localhost ~]# [ -d /test ];echo $?
0
[root@localhost ~]#
- 15、引号
'' 强引用(在单引号中都视为普通字符)
" " 弱引用 (在双引号中保留变量)
[root@localhost ~]# x=111
[root@localhost ~]# echo "$x"
111
[root@localhost ~]# echo '$x'
$x
[roo
- 16、;与&&与||连接多条命令
[root@localhost home]# gagaga;ls # 不论前一条命令运行成功与否,都会执行后续命令
bash: gagaga: 未找到命令...
egon
[root@localhost home]# gagaga && ls # [root@egon ~]# :
[root@egon ~]# echo $?
0只有前一条命令执行成功,才会执行后续命令
bash: gagaga: 未找到命令...
[root@localhost home]# ls /test || mkdir /test # 前一条命令执行不成功才会执行后续命令
0.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
- 17、:空命令,真值
在这里插入代码片
-
18、/路径分隔符
-
19、{}循环列表
[root@localhost home]# touch /test/{0..9}.txt
[root@localhost home]# ls /test/
0.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
[root@localhost ~]# touch {1..3}{a..d}.txt
[root@localhost ~]# ls
1a.txt 1b.txt 1c.txt 1d.txt 2a.txt 2b.txt 2c.txt 2d.txt 3a.txt 3b.txt 3c.txt 3d.txt
[root@egon ~]# x=100
[root@egon ~]# echo ${x}% # 控制变量名的范围
100%
[root@egon ~]#
[root@egon ~]# echo $xrmb
[root@egon ~]# echo ${x}rmb
100rmb
- 20、重定向
> >> 输出重定向
< << 输入重定向
> 覆盖 >> 追加
[root@localhost home]# cat >> a.txt << EOF
> 111
> 222
> 333
> EOF
0标准输入、1标准正确输出、2标准错误输出,&标准正确和错误输出
[root@localhost home]# pwd 1>a.txt
[root@localhost home]# cat a.txt
/home
[root@localhost home]# gagag 2>a.txt
[root@localhost home]# cat a.txt
bash: gagag: 未找到命令...
[root@localhost home]# gagaga &>/dev/null
< << 输入重定向
[root@localhost ~]# mysql -uroot -p123 < bbs.sql
[root@localhost home]# grep root < /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost home]# dd if=/dev/zero of=/a.txt bs=1M count=10
记录了10+0 的读入
记录了10+0 的写出
10485760字节(10 MB)已复制,0.024387 秒,430 MB/秒
[root@localhost home]# dd </dev/zero >/b.txt bs=1M count=10
记录了10+0 的读入
记录了10+0 的写出
10485760字节(10 MB)已复制,0.0202365 秒,518 MB/秒
[root@localhost home]# ll /a.txt
-rw-r--r--. 1 root root 10485760 8月 13 16:02 /a.txt
[root@localhost home]# ll /b.txt
-rw-r--r--. 1 root root 10485760 8月 13 16:03 /b.txt
- 21、?任意一个字符
[root@localhost ~]# ls ??.txt
aa.txt
[root@localhost ~]# ls a?c.txt
a1c.txt
[root@localhost ~]# rm -rf *.txt
- 22、范围中的任意一个字符 [12] [ac] [a-z] [0-9]
[root@localhost ~]# touch a1c a2c axc aXc axd
[root@localhost ~]# ls a?c
a1c a2c axc aXc
[root@localhost ~]# ls a[1x]c
a1c axc
[root@localhost ~]# ls a[a-z]c
axc aXc
[root@localhost ~]# ls a[A-Z]c # 不区分大小写
axc aXc
[root@localhost ~]# ls a[x]c
axc
[root@localhost ~]# ls a[X]c
aXc
[root@localhost ~]# ls a[0-9]c
a1c a2c
[root@localhost ~]# ls /dev/sd[a-z]*
/dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb1