当前位置:   article > 正文

shell编程及自动化运维实现(二)_-ge 7 shell

-ge 7 shell

shell编程及自动化运维实现

第二章:判断

shell条件测试
无论什么编程语言都离不开条件判断(流控),shell也不例外。

例如:用户输入的密码不够长时提示用户,太短了。

例如:用户输入了备份的目录,如果目录存在,继续备份,如果没有目录创建目录。

shell条件测试:
1)数值比较
2)文件测试
3)字符串测试
4)and or
控制流程:if
1)单分支
2)双分支结构
3)多分支结构
4)嵌套结构(了解)
5)调试脚本
6)注意
模式匹配case

1)数值比较:(整数1 操作符 整数2)
操作符:
-gt 大于:[ 20 -gt 10 ]

-lt 小于:[ 10 -lt 20 ]

-eq等于:[  10 -eq 10   ]

-ne不于:[   1 -ne 10 ]

-ge大于等于:[  20 -ge 10 ]

-le小于等于:[10 -le 10 ]


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
示例:
需求:猜测用户输入的密码,是否满足长度的需求

过渡:


变量长度:如何查看变量长度
[root@localhost ~]# pass=12345678
[root@localhost ~]# echo ${#pass}       //查看变量长度
8
  • 1
  • 2
  • 3
  • 4
  • 5

测试语法:

格式一:

test 条件表达:

在这里插[root@localhost ~]# pass=12345678
[root@localhost ~]# test ${#pass} -ge 7   //ge 表示大于等于
[root@localhost ~]# echo $?  //长度为8大于7执行成功
0

[root@localhost ~]# pass=123           
[root@localhost ~]# test ${#pass} -ge 7 //ge表示大于等于
[root@localhost ~]# echo $? //长度为3小于7执行失败
1入代码片
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

格式二:

[条件表达式]:

[root@localhost ~]# [ ${#pass} -ge 7 ] 
[root@localhost ~]# echo $?
1
注意:中括号和字符之间要有空格
  • 1
  • 2
  • 3
  • 4

格式三:

[[条件表达式]]

[root@localhost ~]# [[ ${#pass} -ge 7 ]]
[root@localhost ~]# echo $?
1
注意:中括号和字符之间要有空格
  • 1
  • 2
  • 3
  • 4

if语法结构:

if 如果 条件成立

then 那么 完成指令1 …

else 否则 完成指令2…

fi 结束

脚本:

#!/bin/bash
read -p "please input your passwd:" passwd //请输入你的密码
if test ${#passwd} -lt  7  //如果输入的密码小于7位
then
    echo  "reset your passwd" //就输出重置密码
else
   exit 0 //若密码大于7位,则退出,验证码为0 
fi       
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

测试:

root@localhost ~]# bash 1.sh
please input your passwd:123244
reset your passwd   //当前密码小于7位,重新设置密码代码片
  • 1
  • 2
  • 3
[root@localhost ~]# bash 1.sh
please input your passwd:12345678
[root@localhost ~]# echo $?
0                             //当前密码长度大于7位,验证码为1
  • 1
  • 2
  • 3
  • 4

$? 为0 表示语句执行成功
$? 为1-255 表示语句执行失败

2)文件测试:[ 操作符 文件或者目录 ]
操作符(了解):

-f filename : 当filename 存在时返回真
-b filename : 当filename 存在并且是块文件时返回真(返回0)
-d pathname : 当pathname 存在并且是一个目录时返回真
-h filename : 当filename 存在并且是符号链接文件时返回真 (或 -L filename)
-c filename : 当filename 存在并且是字符文件时返回真
-e pathname : 当由pathname 指定的文件或目录存在时返回真
-g pathname : 当由pathname 指定的文件或目录存在并且设置了SGID 位时返回真
-k pathname : 当由pathname 指定的文件或目录存在并且设置了"粘滞"位时返回真
-p filename : 当filename 存在并且是命名管道时返回真
-r pathname : 当由pathname 指定的文件或目录存在并且可读时返回真
-s filename : 当filename 存在并且文件大小大于0 时返回真
-S filename : 当filename 存在并且是socket 时返回真
-t fd : 当fd 是与终端设备相关联的文件描述符时返回真
-w pathname : 当由pathname 指定的文件或目录存在并且可写时返回真
-x pathname : 当由pathname 指定的文件或目录存在并且可执行时返回真
-O pathname : 当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母O 大写)
-G pathname : 当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真

示例
需求:用户输入路径,如果目录存在则输出目录已存在可以备份,若不存在输出请新建一个目录
脚本:
#!/bin/nash
read -p "please input your diectory:" diectory //请输入的你目录
if [ -d  $diectory ];then //如果目录存在
 echo "The diectory  is exit!you can copy it"//输出目录已经存在,你可以备份
else
  echo "please create a new diectory"  //请新建一个新的目录
fi                                                                                                 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

测试:

[root@localhost ~]# bash 2.sh 
please input your diectory:/tmp
The diectory  is exit!you can copy it  //tmp目录存在


[root@localhost~]# bash 2.sh 
please input your diectory:/etc/passwd //etc下passwd目录不存在
please create a new diectory
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
3)字符串测试[ “字符串”=“字符串” ]:

=等于:需求:邀请用户确认,yes升级装备,no不升级装备

脚本:

#!/bin/bash
read  -p "are you sure updating this equipment:[yes/no] " select
if [ "$select" = "yes" ];then//如果输入等于yes,就输出升级装备
echo "shenjizhuangbei"
else
echo "bushengjizhuangbei"

fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

测试:

[root@localhost ~]# bash select.sh
are you sure updating this equipment:[yes/no] yes
shenjizhuangbei
[root@localhost ~]# bash select.sh
are you sure updating this equipment:[yes/no] no
bushengjizhuangbei
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

常见错误:字符串未加引号。

!=不等于:注意谈好和等号之间没有空格

#!/bin/bash
read  -p "are you sure updating this equipment:[yes/no] " select
if [ "$select" != "yes" ];then //如果输入不等于yes,就输出升级装备
echo "shenjizhuangbei"
else
echo "bushengjizhuangbei"

fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

测试:

[root@localhost ~]# vim select.sh
[root@localhost ~]# bash select.sh
are you sure updating this equipment:[yes/no] no
shenjizhuangbei
[root@localhost ~]# bash select.sh
are you sure updating this equipment:[yes/no] yes
bushengjizhuangbei
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

-z:判断字符长度是为0(了解)

[root@localhost ~]# BBB="" ;test -z $BBB;echo $? //BBB长度为0
0
[root@localhost ~]# BBB="234" ;test -z $BBB;echo $?//BBB长度不为0
1
  • 1
  • 2
  • 3
  • 4

-n:判断字符长度不是为0

[root@localhost ~]# BBB="234" ;test -n  $BBB;echo $?///BBB长度不为0
0
  • 1
  • 2
4) and 和 or:

当条件测试比较复杂时,需要多个条件同时成立,就需要混合条件测试了。

逻辑的(and)与(or)

&&:逻辑的AND的意思。 -a,两个条件同时成立为真。

||:逻辑的OR的意思。-o,两个条件一个成立,为真。

示例:猜测用户输入密码是否满足如下条件:

1.长度大于等于7位

2.包含字母大写

3.包含字母小写

4.包含符号“@L”

#!/bin/bash
read -p "please input your passwd:" pass
if [ ${#pass} -gt  7  ] &&[[ ${pass} =~ [a-z] ]] && [[ ${pass} =~ [A-Z] ]] && [[ ${pass} =~ @_! ]] ;then
echo "your passwd is safe"
else
echo "your passwd is too short,please change it"
fi

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

=~:模糊查询,包含于的意思

这里使用了正则表达式:
匹配括号内内容 :[ ]
匹配小写字母:[:lower:] [a-z]
匹配大写字母:[A-Z] [:upper:]
匹配字母(不分大小写):[:alpha:]
匹配字母数字字符:[:alnum:]
匹配数字:[:digit:] [0-9]

测试:

[root@localhost ~]# bash testpass.sh
please input your passwd:123456aA@_!
your passwd is safe
  • 1
  • 2
  • 3

多种表达方式(了解):

在这里插[root@localhost ~]#[ 1-lt 2 -a 5 -gt 10] //1小于2并且5大于等于10
[root@localhost ~]# [ 1 -lt 2 -a 5 -gt 10 ]
[root@localhost ~]# echo $?
1

[root@localhost ~]#[ 1-lt 2 -o 5 -gt 101小于2或者5大于等于10
[root@localhost ~]# [ 1 -lt 2 -o 5 -gt 10 ]
[root@localhost ~]# echo $?
0入代码片
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

流程控制:if

单分支结构:

if [  command/test ] ; then

    符合该条件执行的语句

 fi
  • 1
  • 2
  • 3
  • 4
  • 5

需求:编写脚本,由用户输入用户名,如果用户不存在,则创建该用户

先了解一下$?变量

如果为真 echo $?为0

如果为假``echo$?为1
脚本:

#/bin/bash
read -p "please input your username :" name
id $name &> /dev/null  
if [ $? -ne  0 ]; then //如果上一句执行不成功$?为0,则创建用户
    useradd $name
   echo "$name  is created"
fi                

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

测试:

[root@localhost ~]# bash userdaa.sh
please input your username :root //root用户已经存在不做任何的反应
[root@localhost ~]# bash userdaa.sh
please input your username :66889 //66889用户不存在,重新创建
66889  is created
  • 1
  • 2
  • 3
  • 4
  • 5

双分支结构:

if 条件测试

 then

命令序列

else

命令序列

fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

示例1:写脚本,由用户输入用户名,如果用户不存在,则创建该用户,否则提示已经存在,
脚本:

#/bin/bash
read -p "please input your username :" name
id $name &> /dev/null
if [ $? -ne  0 ]; then
    useradd $name
   echo "$name  is created"
else
  echo "user is already exist"
fi       
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

测试:

[root@localhost ~]# bash userdaa.sh
please input your username :root
user is already exist
  • 1
  • 2
  • 3

示例2:写脚本,由用户输入用户名,如果用户不存在,则创建该用户,否则提示已经存在,并且设置密码为123456
脚本:

#/bin/bash
read -p "please input your username :" name
if  id $name &> /dev/null; then
    echo "user is already exist"
   
else
   useradd $name
   echo "123456" |  passwd--stdin $name &>/dev/null
 
 echo "$name  is created  passwd is 123456"

fi        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

测试:

[root@localhost ~]# bash userdaa.sh
please input your username :root 
user is already exist  //用户已经存在


[root@localhost ~]# bash userdaa.sh
please input your username :98705
98705  is created  passwd is 123456 //用户不存在,创建用户,并且设置密码为123456
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

多分支结构:

if 条件测试1

 then

命令序列

elif 条件测试2

 then

命令序列


elif 条件测试3

 then
命令序列
.....
else
命令序列
fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

需求:编写脚本,取出系统时间的小时,对数字进行判断

6-10:this is moring

11-13:this is noon

14 -18:this is afternoon

其他:this is night

脚本:

#!/bin/bash
time=`date +%H`
if  [ $time -ge 6 -a $time -le 10 ];then
echo " this is morning "
elif [ $time -ge 11 -a $time -le 13 ];then
echo " this is noon  "
elif [ $time -ge 14 -a $time -le 18 ];then
echo "this is afternoon"
else
 echo  "this is night"
fi
~    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

测试:

[root@localhost ~]# bash time.sh
this is night
  • 1
  • 2

还可以将time.sh放入开机文件:

[root@localhost ~]# vim ~/.bash_profile
  • 1
export /root/time.sh             //在最后一行加入
  • 1

在开机时就会显示

嵌套结构(了解):

if 条件测试1 then 命令序列
   if 条件测试1 then 命令序列
   else 命令序列
   fi
else  命令序列
fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
存在 then
不存在 else
输入用户名
1.创建用户 2.提示用户输入密码
提示已存在
密码位数大于7
创建用户
密码位数小于7
密码错误

示例:

read -p "Input username: " name
id $name &> /dev/null

if [  $? -eq 0   ];then?
echo "$name 存在"

else
        useradd $name
        echo "$name create finished"
        read -p "请输入用户密码: "  pass
                if [ ${#pass}  -ge  7  ];then
                echo "$pass" | passwd --stdin $name
                echo "$name 用户密码是 $pass"
                else
                echo "密码不合格" 
                fi

fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

调试脚本:

方法:#sh-n 02.sh仅调试脚本中的语法错误

​ #sh-vx 02.sh 以调试的方式执行,查询整个执行过程

测试:

第一种:

#!/bin/bash
time=`date +%H`
if  [ $time -ge 6 -a $time -le 10 ];then
echo " this is morning "
elif [ $time -ge 11 -a $time -le 13 ];then
echo " this is noon  "
elif [ $time -ge 14 -a $time -le 18 ];then
echo "this is afternoon"
else
 echo  "this is night"
#fi
把最后一行fi给注释掉,会出现语法错误
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
[root@localhost ~]# bash -n time.sh
time.sh: line 12: syntax error: unexpected end of file
  • 1
  • 2

第二种:

这些是调试信息:背后运行的过程

[root@localhost ~]# bash -vx time.sh
#!/bin/bash
time=`date +%H`
date +%H
++ date +%H
+ time=19
if  [ $time -ge 6 -a $time -le 10 ];then
echo " this is morning "
elif [ $time -ge 11 -a $time -le 13 ];then
echo " this is noon  "
elif [ $time -ge 14 -a $time -le 18 ];then
echo "this is afternoon"
else
 echo  "this is night"
fi
+ '[' 19 -ge 6 -a 19 -le 10 ']' //目前时间是19:39,19是否大于6,小于10
+ '[' 19 -ge 11 -a 19 -le 13 '']' //19是否大于11,小于13
+ '[' 19 -ge 14 -a 19 -le 18 ']'  //19是否大于14,小于18
+ echo 'this is night' 
this is night
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

注意:1、[ ]表示条件测试。注意这里的空格很重要。要注意在’[‘后面和’]'前面都必须要有空格

​ 2、在shell中,then和fi是分开的语句。如果要在同一行里面输入,则需要用分号将他们隔开。

​ 3、注意if判断中对于变量的处理,需要加引号,以免一些不必要的错误。没有加双引号会在一些含空格等的字符串变量判断的时候产生错误。比如[ -n “$var” ]如果var为空会出错。

​ 4、判断是不支持浮点值的。

​ 5、如果只单独使用>或者<号,系统会认为是输出或者输入重定向,虽然结果显示正确,但是其实是错误的,因此要对这些符号进行转意。

​ 6、默认,运行if语句中的命令,所产生的错误信息。仍然出现在脚本的输出结果中

​ 7、使用-z或者-n来检查长度的时候,没有定义的变量也为0

​ 8、空变量和没有初始化的变量可能会对shell脚本测试产生灾难性的影响,因此在不确定变量的内容的时候,在测试号前使用-n或者-z测试一下

​ 9、$? 变量包含了之前执行命令的退出状态(最近完成的前台进程)(可以用于检测退出状态)

模式匹配case:

案例1:

邀请用户输入待删除用户名。
询问用户,确定要继续删除吗 yes/no: " y
if写法:

#!/bin/bash
read -p "please input a username:" user
read -p "Do you wang to delete it?[yes/no]:" option
if [ "$option" = "yes" ];then
   userdel -r $user
   else
       echo "Thank you"
fi   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
测试:
[root@localhost ~]# bash user.sh
please input a username:lili
Do you wang to delete it?[yes/no]:yes
  • 1
  • 2
  • 3
  • 4

语法结构:


case 变量 in
	模式1)
	命令序列1
	;;

	模式2)
	命令序列2
	;;

	模式3)
	命令序列3
	;;

	*)
	无匹配后命令序列
    ;;
	esac

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

case写法:

#!/bin/bash
read -p "please input a username:" user
read -p "Do you wang to delete it?[yes/no]:" option
case "$option" in
yes)
userdel -r $user
echo "$user is delete"
;;
*)
echo "Thank you"
;;
esac
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

测试:

测试:
[root@localhost ~]# bash user.sh 
please input a username:jack     
Do you wang to delete it?[yes/no]:yes
jack is delete
  • 1
  • 2
  • 3
  • 4
  • 5

案例2:

​ 1、显示如下菜单:

​ cpu) show cpu info;

​ mem) show memory info;

​ quit) quit

​ Enter your option:

​ 2、如果用户选择cpu,则显示文件/proc/cpuinfo的信息;

​ 3、如果用户选择mem,则显示文件/proc/meminfo的信息;

​ 4、如果用户选择quit,则退出,且退出码为5;

脚本:

#!/bin/bash
cat <<EOF
cpu) show cpu info;
mem) show memory info;
quit) quit
EOF
read -p "please inout your select:" select
case "$select" in
cpu)
cat /proc/cpuinfo
;;
mem)
cat /proc/meminfo
;;
*)
exit 5
;;
esac
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

测试:输入CPU

[root@localhost ~]# bash server.sh
cpu) show cpu info;
mem) show memory info;
quit) quit
please inout your select:cpu
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 94
model name	: Intel(R) Core(TM) i5-6300HQ CPU @ 2.30GHz
stepping	: 3
microcode	: 0xcc
cpu MHz		: 2302.824
cache size	: 6144 KB
physical id	: 0
siblings	: 1
core id		: 0
cpu cores	: 1
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

测试:输入quit

[root@localhost ~]# bash server.sh
cpu) show cpu info;
mem) show memory info;
quit) quit
please inout your select:quit
[root@localhost ~]# echo $?
5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

案例3:

linux提供的丰富的管理命令,用户管理,内存管理,磁盘管理,进程管理,日志管理,文件管理,软件管理,网络管理等等数十个工具包。
如果你能通过shell编程,把他们编写到一个程序里。想用某些功能,只需要按回车,就能完成。

Command action
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序

Command (h for help): m
total used free shared buffers cached
Mem: 7628 840 6788 0 29 378
Swap: 2047 0 2047

-EOF:支持tab

#!/bin/bash
#print list
cat <<EOF
please choose your tools:
h.help information
f.disk information
d.file system 
m.memory information
u.xitongfuzaiixinxi
q.exit
EOF
read -p "your choose:" option
case $option in
h)
echo "please input alpha entry the box"
;;
f)
fdisk -l
;;
d)
mount
;;
m)
free -m
;;
u)
uptime
;;
q)
echo"Thank you"
exit
;;
esac
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

测试:

输入h

root@localhost ~]# bash manager.sh
please choose your tools:
h.help information
f.disk information
d.file system 
m.memory information
u.xitongfuzaiixinxi
q.exit
your choose:h
please input alpha entry the box
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

输入f

[root@localhost ~]# bash manager.sh
please choose your tools:
h.help information
f.disk information
d.file system 
m.memory information
u.xitongfuzaiixinxi
q.exit
your choose:f

Disk /dev/sda: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000e2890

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      411647      204800   83  Linux
/dev/sda2          411648    25593855    12591104   8e  Linux LVM

Disk /dev/mapper/centos-root: 10.7 GB, 10737418240 bytes, 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

多加练习才能掌握,大家可以参考我写的案例,动手练一练。
最后:由于我的xshell不支持中文输入,所以有些指示写的我蹩脚的英文,请见谅。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/111642
推荐阅读
相关标签
  

闽ICP备14008679号