1、案例1(表达式案例):
开发shell脚本分别实现以定义变量,脚本传参以及read读入的方式比较2个整数大小。用条件表达式(禁if)
进行判断并以屏幕输出的方式提醒用户比较结果;
[root@backup ~]# echo "123a" | sed -r "s#[0-9]##g"
a
(1)[root@backup ~]# cat c1.sh
#!/bin/sh
read -p "please input tow num:" num1 num2
a=$num1
b=$num2
#no.1
[ -z "$a" -o -z "$b" ]&&{
echo "USAGE: num1 num2"
exit 1
}
#no.2
[ "`echo "$a"|sed -r 's#[^0-9]##g'`" = "$a" ]||{ #判断两个数字是整数
echo "first arg must be int"
exit 1
}
[ "`echo "$b"|sed -r 's#[^0-9]##g'`" = "$b" ]||{
echo "second arg must be int"
exit 1
}
#no.3
[ $a -eq $b ]&&{
echo "$a=$b"
exit 0
}
[ $a -gt $b ]&&{
echo "$a>$b"
exit 0
}
[ $a -lt $b ]&&{
echo "$a<$b"
exit 0
}
[root@backup ~]# sh c1.sh
please input tom num:1 2
1<2
(2)[root@backup ~]# cat c2.sh
#!/bin/sh
#no.1
[ $# -ne 2 ]&&{
echo "USAGE: num1 num2"
exit 1
}
#no.2
[ "`echo "$1"|sed -r 's#[^0-9]##g'`" = "$1" ]||{
echo "first arg must be int"
exit 1
}
[ "`echo "$2"|sed -r 's#[^0-9]##g'`" = "$2" ]||{
echo "second arg must be int"
exit 1
}
#no.3
[ $1 -eq $2 ]&&{
echo "$1=$2"
exit 0
}
[ $1 -gt $2 ]&&{
echo "$1>$2"
exit 0
}
[ $1 -lt $2 ]&&{
echo "$1<$2"
exit 0
}
[root@backup ~]# sh c2.sh 1 2
1<2
(3)[root@backup scripts]# vim c2.sh
#!/bin/sh
#no.1
if [ $# -ne 2 ];then
echo "USAGE: num1 num2"
exit 1
fi
#no.2
if [ "`echo "$1"|sed -r 's#[^0-9]##g'`" != "$1" ];then #将整型转换成字符串做判断
echo "first arg must be int"
exit 1
fi
if [ "`echo "$2"|sed -r 's#[^0-9]##g'`" != "$2" ];then
echo "second arg must be int"
exit 1
fi
#no.3
if [ $1 -eq $2 ];then
echo "$1=$2"
elif [ $1 -gt $2 ];then
echo "$1>$2"
else
echo "$1<$2"
fi
(4)[root@backup scripts]# vim c2.sh
#!/bin/sh
#no.1
if [ $# -ne 2 ];then
echo "USAGE: num1 num2"
exit 1
fi
#no.2
if [ "`echo "$1"|sed -r 's#[^0-9]##g'`" != "$1" -o "`echo "$2"|sed -r 's#[^0-9]##g'`" != "$2" ];then
echo "input arg must be init"
else
if [ $1 -eq $2 ];then
echo "$1=$2"
elif [ $1 -gt $2 ];then
echo "$1>$2"
else
echo "$1<$2"
fi
fi
2、小案例二(if案例):
打印菜单
(1)[root@backup scripts]# cat c3.sh
#!/bin/sh
menu() {
cat <<END
1.[install lamp]
2.[install lnmp]
3.[exit]
please input the num you want:
END
}
menu
read num
if [ "$num" = "1" -a -x /server/scripts/lamp.sh ];then
echo "start installing lamp"
/bin/sh /server/scripts/lamp.sh
echo "lamp is starting"
fi
if [ "$num" = "2" -a -x /server/scripts/lnmp.sh ];then
echo "start installing lnmp"
/bin/sh /server/scripts/lnmp.sh
echo "lnmp is starting"
fi
if [ "$num" = "3" ];then
echo "exit install now"
fi
if [ "$num" != "1" -a "$num" != "2" -a "$num" != "3" ];then
echo "you put error"
fi
(2)[root@backup ~]# vim c3.sh
#!/bin/sh
menu() {
cat <<END
1.[install lamp]
2.[install lnmp]
3.[exit]
please input the num you want:
END
}
menu
read num
[ "$num" = "1" -a -x /server/scripts/lamp.sh ]&&{
echo "start installing lamp"
/bin/sh /server/scripts/lnmp.sh
echo "lamp is starting"
exit 0
}
[ "$num" = "2" -a -x /server/scripts/lnmp.sh ]&&{
echo "start installing lamp"
/bin/sh /server/scripts/lnmp.sh
echo "lnmp is starting"
exit 0
}
[ "$num" = "3" ]&&{
echo "exit install now"
exit 0
}
echo "input error"
exit 1
[root@backup ~]# sh c3.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
please input the num you want:
1
start installing lamp
lamp
3、监控案例:
(1)端口监控:
1)本地监控:
本地:netstat/lsof
[root@backup ~]# df -h |awk -F "[ ]+" 'NR==2{print $5}' #监听磁盘;
4%
[root@backup ~]# vim /etc/mail.rc #配置邮件服务
set from=hyjy2504164765@163.com smtp=smtp.163.com smtp-auth-user=hyjy2504164765 smtp-auth-password=linux123 smtp-auth=login
[root@backup ~]# vim c4.sh #监听内存
#!/bin/sh
a=`free -m|awk 'NR==3{print $NF}'`
if [ $a -lt 700 ]
then
echo `free -m` >/tmp/memory.txt
mail -s " backup_server memory exhaust" hyjy2504164765@163.com </tmp/memory.txt
fi
netstat -tunlp|grep 3306|wc -l #监听mysql服务器;
netstat -tunlp|grep mysqld|wc -1
lsof -i tcp:3306|wc -l
[ "`netstat -tunlp|grep 3306|awk -F "[ :]+" '{print $5}'`" = "3306" ] #最差的方法,如果使用-eq,当mysqld没有启动时 #会导致空值,整数无法比较,报错;而空字符串是可以比较的;
[root@backup ~]# cat c5.sh #监听mysqld
#/bin/sh
if [ `netstat -tunlp|grep 3306|wc -l` -ne 0 ];then
echo "mysqld is starting"
else
echo "mysqld is not start"
/etc/init.d/mysqld start &>/dev/null
echo "mysqld is starting……"
fi
crontab -e
03 00 * * * /bin/sh /root/c4.sh >/dev/null 2>&1
2)远程监控:
远程:telnet/nmap/
[root@backup scripts]# echo -e "\n"|telnet www.baidu.com 80|grep Connected|wc -l
Connection closed by foreign host.
1
[root@backup scripts]# nmap www.baidu.com -p 80|grep open|wc -l
1
[ `nmap www.baidu.com -p 80|grep open|wc -l` -ne 0 ]
(2)进程监控:
1)本地监控:
[root@backup scripts]# ps -ef | grep "httpd"|grep -v "grep"|wc -l
10
(3)web监控:
1)网站是否正常监控:
[root@backup scripts]# cat c7.sh
#!/bin/sh
#[ "`curl -s http://172.16.1.41 &>/dev/null&&echo $?`" = "0"] #根据返回的页面;
#[ "`curl -s http://172.16.1.41`" = "bbs" ] #根据返回的页面;
#[ "`curl -I -s http://172.16.1.41|head -1|egrep -o "200|301|302|"|wc -l`" = "1" ] #根据返回消息头的状态码;
if [ "`curl -I -s -o /dev/null -w "%{http_code}\n" http://172.16.1.41`" = "200" ] #-I 响应头信息;-s 安静模式 ;-o:返回为null;-w 状态码;
then
echo "HTTPD is running"
else
echo "httpd is stop"
/etc/init.d/httpd start
fi
4、通过一条命令计算输出1+2+3+….+10的表达式,并计算出结果,使用bc进行计算:
(1)生成表达式的方法:
[root@backup scripts]# echo {1..10}|tr " " "+"
1+2+3+4+5+6+7+8+9+10
[root@backup scripts]# seq -s "+" 10
1+2+3+4+5+6+7+8+9+10
(2)实现的方法:
[root@backup scripts]# echo `echo {1..10}|tr " " +"`=`echo {1..10}|tr " " "+"|bc`
1+2+3+4+5+6+7+8+9+10=55
其它方法:
[root@backup scripts]# echo `seq -s "+" 10`=$((`seq -s "+" 10`))
1+2+3+4+5+6+7+8+9+10=55
[root@backup scripts]# echo `echo {1..10} | tr " " "+"`=$((`echo {1..10} | tr " " "+"`))
1+2+3+4+5+6+7+8+9+10=55
[root@backup scripts]# echo `seq -s "+" 10`=`seq -s " + " 10|xargs expr`
1+2+3+4+5+6+7+8+9+10=55
5、实现通过传参的方式往/etc/user.conf里添加用户:
(1)具体要求如下:
1)命令用法:
USAGE: sh adduser {-add|-del|-search} username
2)传参要求:
如果参数为-add时,表示添加后面接的用户名;
如果参数为-del时,表示删除后面接的用户名;
如果参数为-search时,表示查找后面接的用户名;
3)如果有同名的用户则不能添加,没有对应用户则无需删除,查找到用户以及没有用户时给出明确提示;
4)/etc/user.conf不能被所有外部用户直接删除及修改
(2)代码:
"\<字符\>":表示一行中只有该字符,没有其它的字符;
1)使用case法;
[root@backup scripts]# vim c8.sh
#!/bin/bash
username=$2
args=$1
file=/etc/user.conf
if [ $# -ne 2 ];then
echo "USAGE:$0 {-add|-del|-search} username"
exit 1
fi
case "$args" in
-add|--add)
if [ `grep "\<$username\>" /etc/user.conf |wc -l` -ne 0 ];then
echo "$username user exist"
else
echo $username >>$file
echo "$username add success"
fi
;;
-del|--del)
if [ `grep "\<$username\>" /etc/user.conf |wc -l` -eq 0 ];then
echo "$username not exist"
else
sed -i "/\<$username\>/d" $file
echo "$username delete success"
fi
;;
-search|--search)
if [ `sed -n "/\<$username\>/p" $file |wc -l` -eq 0 ];then
echo " $username not find"
else
echo $username
fi
;;
*)
echo "error arg"
exit 1
esac
2)使用case和function法:
[root@backup scripts]# cat c12.sh
#!/bin/bash
file=/etc/user.conf
function checkfile() {
[ -f $file ] || {
touch /etc/user.conf
chmod 700 /etc/user.conf
}
}
function adduser() {
checkfile
if [ `grep "\<$1\>" /etc/user.conf |wc -l` -ne 0 ]; then
echo "$1 user exit"
else
echo "$1" >>$file
echo "$1 add success"
fi
}
function deluser() {
if [ `grep "\<$1\>" /etc/user.conf |wc -l` -eq 0 ]; then
echo "$1 not exist"
else
sed -i "/\<$1\>/d" $file
echo "$1 delete success"
fi
}
function searchuser() {
if [ `sed -n "/\<$1\>/p" $file |wc -l` -eq 0 ]; then
echo "$1 not find"
else
echo "$1"
fi
}
function error() {
echo "error arg"
exit 1
}
function sel() {
case "$1" in
-add|--add)
adduser $2
;;
-del|--del)
deluser $2
;;
-search|--search)
searchuser $2
;;
*)
error
;;
esac
}
function main() {
if [ $# -ne 2 ]; then
echo "USAGE:$0 {-add|-del|-search} username"
exit 1
else
sel $1 $2
fi
}
main $*
6、监听网站脚本:
(1)脚本:
[root@backup scripts]# cat c13.sh
#!/bin/sh
[ -f /etc/init.d/functions ] && . /etc/init.d/functions || exit 1
function usage() {
echo "USAGE:$0 url"
exit 1
}
RETVAL=0
function check() {
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
action "url $1" /bin/true
else
action "url $1" /bin/false
fi
}
function checkurl() {
#-T 10:延迟时间为10s;--spilder:爬取页面;-t 2:重新尝试次数为2;
wget -T 10 --spider -t 2 $1 &>/dev/null
check $1
#if [ "`curl -I -s http://$url|head -1|egrep -o "200|301|302|"|wc -l`" = "1" ]; then
# check $1
#else
# check $1
#fi
}
function main() {
if [ $# -ne 1 ]; then
usage
else
checkurl $1
fi
}
main $*
(2)测试:
[root@backup scripts]# sh c13.sh www.sina.comfd
url www.sina.comfd [失败]
[root@backup scripts]# sh c13.sh www.sina.com
url www.sina.com [确定]
7、根据输入的颜色和内容打印相应颜色的内容:
[root@backup scripts]# vim c14.sh
#!/bin/sh
RED_COLOR="\E[1;31m"
GREEN_COLOR="\E[1;32m"
YELLOW_COLOR="\E[1;33m"
BLUE_COLOR="\E[1;34m"
RES="\E[0m"
SHAN="\E[1;31;5m"
SHANEND="\E[0m"
function usage() {
echo -e "$SHAN USAGE:$0 {red|green|yellow|blue} contents $SHANEND"
}
function selt() {
case "$1" in
red)
echo -e "${RED_COLOR} $2 ${RES}"
;;
green)
echo -e "$GREEN_COLOR $2 $RES"
;;
yellow)
echo -e "$YELLOW_COLOR $2 $RES"
;;
blue)
echo -e "$BLUE_COLOR $2 $RES"
;;
*)
usage
esac
}
function main() {
if [ $# -ne 2 ]; then
usage
exit 1
else
selt $1 $2
fi
}
main $*
8、定制nginx启动服务,并加入到开机自启动中:
(1)编写代码:
[root@m01 server]# cat nginxd
# chkconfig: 345 60 63
#!/bin/sh
[ /etc/init.d/functions ] && . /etc/init.d/functions || exit 1
pidfile=/application/nginx/logs/nginx.pid
if [ $UID -ne 0 ]; then
echo "this scripts should run root user"
exit 1
fi
RETVAL=0
function check(){
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
action "$1" /bin/true
else
action "$1" /bin/false
fi
}
function usage() {
echo "/etc/init.d/nginxd {start|stop|status|restart}"
}
function start_nginx() {
if [ -f $pidfile ]; then
echo "nginx is start……"
else
/application/nginx/bin/nginx &>/dev/null
check "nginx is start"
fi
}
function stop_nginx() {
if [ -f $pidfile ]; then
/application/nginx/bin/nginx -s stop &>/dev/null
check "nginx is stop"
else
echo "nginx is stop……"
fi
}
function status_nginx() {
if [ -f $pidfile ]; then
echo "nginx is rung……"
else
echo "nginx is stop……"
fi
}
function reload_nginx() {
if [ -f $pidfile ]; then
/application/nginx/bin/nginx -s reload &>/dev/null
check "nginx is reload"
else
echo "nginx is stop,not reload"
fi
}
function main() {
if [ $# -ne 1 ]; then
usage
exit 1
else
case "$1" in
start)
start_nginx
;;
stop)
stop_nginx
;;
status)
status_nginx
;;
restart)
stop_nginx
sleep 3
start_nginx
;;
reload)
reload_nginx
;;
*)
usage
;;
esac
fi
}
main $*
(2)加入到/etc/init.d/目录中:
[root@m01 server]# mv -v nginxd /etc/init.d/
[root@m01 server]# chmod u+x /etc/init.d/nginxd
[root@m01 server]# chkconfig --add /etc/init.d/nginxd
(3)测试:
[root@m01 ~]# ps -ef | grep -v grep|grep nginx
[root@m01 ~]# /etc/init.d/nginxd start
nginx is start [确定]
[root@m01 ~]# /etc/init.d/nginxd restart
nginx is stop [确定]
nginx is start [确定]
[root@m01 ~]# ps -ef | grep -v grep|grep nginx
root 2378 1 0 05:06 ? 00:00:00 nginx: master process /application/nginx/bin/nginx
nginx 2380 2378 0 05:06 ? 00:00:00 nginx: worker process
[root@m01 ~]# /etc/init.d/nginxd status
nginx is rung……
[root@m01 ~]# /etc/init.d/nginxd stop
nginx is stop [确定]
[root@m01 ~]# ps -ef | grep -v grep|grep nginx
[root@m01 ~]#
9、手机充值:
例如:冲10元,每发一次短信(输出当前余额)扣1角5分,当余额低于1角5分时不能发短信,提示余额不足,请
充值(可以用户充值继续发短息)使用while语句实现;
提示:单位换算,统一单位“分”
[root@backup scripts]# cat c19.sh
#!/bin/sh
TOTAL=10000
MSG_PEE=3000
function isnum() {
expr $1 + 1 &>/dev/null
if [ $? -ne 0 -a "$1" != "-1" ]; then
return 1 #1代表假;
fi
return 0 #0代表真;
}
function quit() {
read -p "are you want quit?[yes|no]"
}
function gather() {
read -p "pls input your msg:" txt
read -p "are you to send?[yes|no]:" option
case $option in
[Yy]|[Yy][Ee][Ss])
echo "send successfuly!"
((TOTAL=TOTAL-MSG_PEE))
echo "you have $TOTAL"
;;
[Nn]|[Nn][Oo])
echo "send canceld"
;;
*)
echo "invalid input,this msg doesnt send out"
;;
esac
}
function les(){
read -p "money is not enough,are you want to charge[yes|no]:" OPTION
case $OPTION in
[Yy]|[Yy][Ee][Ss])
while true; do
read -p "how much are you want to charge:" charge
isnum $charge && break || echo "invalid input"
done
;;
[Nn]|[Nn][Oo])
exit 1;
;;
*)
echo "invalid input"
;;
esac
echo "you have charge $((TOTAL+=charge))"
charge=0
if [ $TOTAL -lt $MSG_PEE ]; then
echo "you need $((MSG_PEE-TOTAL))"
les
fi
}
function main() {
while true; do
if [ $TOTAL -lt $MSG_PEE ];then
les
else
gather
fi
done
}
main
10、while循环读取日志分析企业案例多种方法:
读取网站访问的流量;
continue :代表结束本次循环进入下一次循环;
break:代表结束整个循环;
(1)
while read line; do
cmd
done<FILE
(2)exec < FILE
while read line; do
cmd
done
(3)代码:
1)[root@backup scripts]# vim c20.sh
#!/bin/sh
sum=0
exec </server/scripts/access_log
while read line; do
i=`echo $line|awk '{print $10}'`
expr $i + 1 &>/dev/null
if [ $? -ne 0 -a "$i" != "-1" ]; then
continue
fi
((sum+=i))
done
if [ -n "$sum" ]; then
echo $sum
fi
2) [root@backup scripts]# vim c20.sh
#!/bin/sh
sum=0
while read line; do
i=`echo $line|awk '{print $10}'`
expr $i + 1 &>/dev/null
if [ $? -ne 0 -a "$i" != "-1" ]; then
continue
fi
((sum+=i))
done </server/scripts/access_log
if [ -n "$sum" ]; then
echo $sum
fi
(4)测试:
[root@backup scripts]# sh c20.sh
11851
11、随机生成文件:
(1)[root@backup scripts]# cat c22.sh
#!/bin/sh
for ((i=1;i<=10;i++)); do
mkdir -p . test/
touch . test/`echo $RANDOM|md5sum|cut -c 1-8`_finished.html
done
12、linux下批量修改文件名:
思路:mv 重命名(awk拼接法,sed替换法),专业方法是rename;
(1)[root@backup scripts]# rename "_finished.html" ".jpg" /server/scripts/*.html
(2)[root@backup test]# ls /server/scripts/test/*.html | awk -F "[_]" '{print "mv",$0,$1".jpg"}'|bash
#常用于find命令;
(3)[root@backup test]# f=4e5a725a_finished.html
[root@backup test]# mv $f `echo $f | sed 's#_finished.html#.jpg#g'`
[root@backup test]# cat c23.sh
#!/bin/sh
for f in `ls /server/scripts/test/*.html`; do
mv $f `echo $f | sed "s#_finished.html#.jpg#g"`
if [ $? -ne 0 ]; then
echo $f >>/tmp/error.log
fi
done
(4)扩展:
[root@backup test]# chkconfig --list | grep 3:启用|awk '{print "chkconfig",$1,"on"}'
13、使用for循环批量创建10个文件;
[root@backup scripts]# cat touchFile.sh
#!/bin/sh
dir=/server/scripts/lc
[ -d $dir ] ||{
mkdir -p $dir
}
for n in `seq 1 10`; do
touch $dir/$n.txt
done
14、批量创建十个系统账号并创建密码,密码是随机数:
(1)创建随机数的方法:
1)[root@backup scripts]# echo $RANDOM
31739
2)[root@backup scripts]# echo $(($RANDOM+11111111))
11142220
3)[root@backup scripts]# echo $RANDOM | md5sum | cut -c 2-9
2a06d071
4)[root@backup scripts]# openssl rand -base64 8 #后面的位数是可以根据需要改变的
4Iq+gr7x0Yc=
5)[root@backup scripts]# date +%s%N | cut -c 2-9 #使用的是时间随机数;
54778341
6)[root@backup scripts]# head /dev/urandom | cksum #设备随机数
2840405153 2734
8)[root@backup scripts]# cat /proc/sys/kernel/random/uuid #系统uuid随机数
9da3376c-0588-4e15-a42f-51560aaea97c
9)[root@backup scripts]# yum install expect -y
[root@backup scripts]# mkpasswd -l 10 #expect随机数,后面字段的长度可以随意改变;
NWhg32ani$
(2)代码:
[root@backup scripts]# cat createpasswd.sh
#!/bin/sh
. /etc/init.d/functions
[ $UID -eq 0 ] || {
echo "only allow root to exec this $0"
exit 1
}
for ((i=1;i<=10;i++)); do
pass=`echo $RANDOM | md5sum | cut -c 2-9`
useradd student$i &>/dev/null
echo "$pass | passwd --stdin student$i" &>/dev/null
if [ $? -eq 0 ]; then
action "useraddd student$i" /bin/true
else
action "useraddd student$i" /bin/false
fi
echo -e "student$i\t$pass" >>/tmp/user.txt
done
说明:如果用户存在就当是更新用户密码了;
(3)运行截图:
[root@backup scripts]# sh createpasswd.sh
useraddd student1 [确定]
useraddd student2 [确定]
useraddd student3 [确定]
useraddd student4 [确定]
useraddd student5 [确定]
useraddd student6 [确定]
useraddd student7 [确定]
useraddd student8 [确定]
useraddd student9 [确定]
useraddd student10 [确定]
15、已知下面的字符串是通过RANDOM随机数变量md5sum|cut-c 1-8截取后的结果,
请破解这些字符串对应的md5sum前的RANDOM对应数字:
21029299
00205d1c
a3da1677
1f6d12dd
890684b
(1)代码:
代码一:
[root@backup scripts]# cat bakrandom.sh
#!/bin/sh
array=(21029299
00205d1c
a3da1677
1f6d12dd
890684b)
for i in {0..32767}; do
passwd=`echo $i | md5sum | cut -c 1-8`
for n in ${array[*]};do
if [ "$n" = "$passwd" ]; then
echo -e "$n\t$i"
fi
done
done
代码二:
[root@db01 scripts]# vim random.sh
#!/bin/sh
array=(21029299
00205d1c
a3da1677
1f6d12dd
890684b)
for i in {0..32767}; do
passwd=`echo $i | md5sum | cut -c 1-8`
for ((n=0;n<${#array[*]};n++));do
if [ "${array[n]}" = "$passwd" ]; then
echo -e "${array[n]}\t$i"
fi
done
done
(2)测试:
[root@backup scripts]# sh bakrandom.sh
00205d1c 1346
1f6d12dd 7041
a3da1677 25345
21029299 25667
提示:890684b #该参数没有相对应的值;
16、请用至少两种方法实现base for循环打印下面这句话中字母数不大于6的单词(昆仑万维面试题):
I am oldboy teacher welcome to oldboy training class.
(1)回顾:
打印字符串长度的方法有:
[root@backup scripts]# a=1234
1)[root@backup scripts]# echo $a | wc -L
4
2)[root@backup scripts]# expr length ${a}
4
3)[root@backup scripts]# echo ${#a}
4
(2)代码:
1)方法一:
[root@backup scripts]# vim filterword.sh
#!/bin/sh
for word in I am oldboy teacher welcome to oldboy training class.; do
if [ ${#word} -le 6 ]; then
echo -en "$word\t"
fi
done
2)方法二:
[root@backup scripts]# vim filterword.sh
#!/bin/sh
array=(I am oldboy teacher welcome to oldboy training class.)
for word in ${array[*]}; do
if [ ${#word} -le 6 ]; then
echo -en "$word\t" #echo -n表示不换行输出
fi
done
3)方法三:
[root@backup scripts]# echo "I am oldboy teacher welcome to oldboy training class." | tr ' ' '\n' | awk '{if(length($1)<=6) print $1}'
(3)测试:
1)方法一、二:
[root@backup scripts]# sh filterword.sh
I am oldboy to oldboy class.
2)方法三:
I
am
oldboy
to
oldboy
class.
17、检查多个网站地址是否正常:
(1)代码:
[root@backup scripts]# cat checkwww.sh
#!/bin/sh
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
array=(
)
RETVAL=0
function check() {
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
action "url $1" /bin/true
else
action "url $1" /bin/false
fi
}
function checkurl() {
#-T 10:延迟时间为10s;--spilder:爬取页面;-t 2:重新尝试次数为2;
wget -T 10 --spider -t 2 $1 &>/dev/null
check $1
#if [ "`curl -I -s http://$url|head -1|egrep -o "200|301|302|"|wc -l`" = "1" ]; then
# check $1
#else
# check $1
#fi
}
function main() {
for n in ${array[*]}; do
checkurl $n
sleep 3
done
}
main
(2)测试:
[root@backup scripts]# sh checkwww.sh
url www.baidu.com [确定]
url www.aliyun.com [确定]
url www.souhu.com [确定]
url www.xina.com [确定]
18、mysql数据分库分表备份脚本:
(1)分库备份操作:
1)获取数据库列表:
[root@db01 ~]# mysql -uroot -p123456 -e "show databases;" | sed '1d' | egrep -v "_schema|mysql"
wordpress
2)脚本编写:
[root@db01 scripts]# cat mysqlbak.sh
#!/bin/sh
export PATH=/application/mysql/bin/:/application/mysql/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
BACKPATH="/server/backup"
mkdir -p $BACKPATH
MYUSER="root"
MYPASS="123456"
MYCMD="mysql -u$MYUSER -p$MYPASS"
# --single-transaction:锁表;-B:数据库名 ;-F:刷新日志文件; -R:转存储的函数;
MYDUMP="mysqldump -u$MYUSER -p$MYPASS --single-transaction --master-data=1 -F -R -B"
DBLIST=`$MYCMD -e "show databases;" | sed '1d' | egrep -v "_schema|mysql"`
for dbname in $DBLIST; do
$MYDUMP $dbname | gzip >$BACKPATH/${dbname}_$(date +%F).sql.gz
done
3)测试:
[root@db01 scripts]# sh mysqlbak.sh
[root@db01 scripts]# ls -lh /server/backup/
总用量 160K
-rw-r--r-- 1 root root 159K 1月 21 21:02 wordpress_2019-01-21.sql.gz
(2)分表备份操作:
1)查看表:
[root@db01 scripts]# mysql -uroot -p123456
mysql> use wordpress;
Database changed
mysql> show tables;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| lc_commentmeta |
| lc_comments |
| lc_links |
| lc_options |
| lc_postmeta |
| lc_posts |
| lc_term_relationships |
| lc_term_taxonomy |
| lc_termmeta |
| lc_terms |
| lc_usermeta |
| lc_users |
+-----------------------+
12 rows in set (0.00 sec)
[root@db01 scripts]# mysql -uroot -p123456 -e "show tables from wordpress;" | sed '1d'
lc_commentmeta
lc_comments
lc_links
lc_options
lc_postmeta
lc_posts
lc_term_relationships
lc_term_taxonomy
lc_termmeta
lc_terms
lc_usermeta
lc_users
2)代码:
[root@db01 scripts]# cat mysqltable.sh
#!/bin/sh
export PATH=/application/mysql/bin/:/application/mysql/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
BACKPATH="/server/backup"
mkdir -p $BACKPATH
MYUSER="root"
MYPASS="123456"
MYCMD="mysql -u$MYUSER -p$MYPASS"
# --single-transaction:锁表;-B:数据库名 ;-F:刷新日志文件; -R:转存储的函数过;
MYDUMP="mysqldump -u$MYUSER -p$MYPASS --single-transaction --master-data=1 -F -R"
DBLIST=`$MYCMD -e "show databases;" | sed '1d' | egrep -v "_schema|mysql"`
for dbname in $DBLIST; do
TLIST=`$MYCMD -e "show tables from $dbname;" | sed '1d'`
mkdir -p $BACKPATH/$dbname
for tname in $TLIST; do
$MYDUMP $dbname $tname | gzip >$BACKPATH/$dbname/${tname}_$(date +%F).sql.gz
done
done
3)测试:
[root@db01 scripts]# sh mysqltable.sh
[root@db01 scripts]# ls /server/backup/wordpress/
lc_commentmeta_2019-01-21.sql.gz lc_options_2019-01-21.sql.gz lc_termmeta_2019-01-21.sql.gz lc_term_taxonomy_2019-01-21.sql.gz
lc_comments_2019-01-21.sql.gz lc_postmeta_2019-01-21.sql.gz lc_term_relationships_2019-01-21.sql.gz lc_usermeta_2019-01-21.sql.gz
lc_links_2019-01-21.sql.gz lc_posts_2019-01-21.sql.gz lc_terms_2019-01-21.sql.gz lc_users_2019-01-21.sql.gz
(3)提示:
1)mysql数据库的还原脚本:
以上的脚本倒着写
gzip -d bak.sql.gz
mysql -uroot -p123456 </tmp/bak.sql
2)备份数据库表时如不能使用-B参数,不然会导致备份时以后备份的是数据库,会报下面的错误;
mysqldump: Got error: 1049: Unknown database 'lc_commentmeta' when selecting the database
mysqldump: Got error: 1049: Unknown database 'lc_comments' when selecting the database
19、mysql启动脚本的编写:
(1)代码:
[root@db01 scripts]# cat mysqlstart.sh
#!/bin/sh
. /etc/init.d/functions
export PATH=/application/mysql/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
MYUSER="root"
MYPASS="123456"
# MYADMIN="mysqladmin -u$MYUSER -p$MYPASS" -S /tmp/mysql.sock
MYADMIN="mysqladmin -u$MYUSER -p$MYPASS"
[ $UID -eq 0 ] || {
echo "please use root"
exit 1
}
function usage (){
echo "USAGE:sh $0 |start|stop|restart|"
}
RETVAL=0
function check() {
if [ $RETVAL -eq 0 ]; then
action "$1" /bin/true
else
action "$1" /bin/false
fi
}
function start() {
# mysqld_safe --defaults-file=/etc/my.cnf &>/dev/null &
mysqld_safe &>/dev/null &
check "start mysql"
}
function stop() {
$MYADMIN shutdown &>/dev/null
check "stop mysql"
}
function main(){
if [ $# -eq 1 ]; then
case "$1" in
start)
start
sleep 2
;;
stop)
stop
sleep 2
;;
restart)
stop
sleep 3
start
;;
*)
usage
;;
esac
else
usage
fi
}
main $*
(2)测试:
[root@db01 scripts]# lsof -i :3306
[root@db01 scripts]# sh mysqlstart.sh start
start mysql [确定]
[root@db01 scripts]# lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 8010 mysql 10u IPv4 28515 0t0 TCP *:mysql (LISTEN)
[root@db01 scripts]# sh mysqlstart.sh stop
stop mysql [确定]
[root@db01 scripts]# lsof -i :3306
[root@db01 scripts]# sh mysqlstart.sh start
start mysql [确定]
[root@db01 scripts]# sh mysqlstart.sh restart
stop mysql [确定]
start mysql [确定]
[root@db01 scripts]# lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 8502 mysql 10u IPv4 28919 0t0 TCP *:mysql (LISTEN)
20、开发脚本防止DOS攻击:
提示:根据web日志或者网络连接数,监控当某个ip并发连接数或者短时间内pv数达到100,即调用防火
墙命令疯掉对应的ip地址,监控频率每个3分钟,防火墙命令为:iptables -I INPUT -s 192.168.1.100 -j DROP;
(1)思路:
1)统计大于100pv的ip和封闭防火墙的命令;
(2)编写代码:
[root@db01 scripts]# cat dosdelip.sh
#!/bin/sh
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
before_ipfile="/tmp/ip_$(date +%F -d '-1day').log"
function del() {
if [ -f $before_ipfile ]; then
exec <$before_ipfile
while read line; do
if [ `iptables -L -n | grep $line | wc -l` -ge 1 ];then
iptables -D INPUT -s $line -j DROP
fi
done
fi
}
del
[root@db01 scripts]# cat dosprotedted.sh
#!/bin/sh
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
function main() {
awk '{print $1}' $1 | sort | uniq -c | sort -rn >/tmp/tmp.log
exec </tmp/tmp.log
while read line; do
ip=`echo $line | awk '{print $2}'`
num=`echo $line | awk '{print $1}'`
if [ "$ip" != " " -a $ip != "::1" ]; then
if [ $num -gt 100 -a `iptables -L -n | grep $ip | wc -l` -lt 1 ]; then
iptables -I INPUT -s $ip -j DROP
echo $ip >>/tmp/ip_$(date +%F).log
fi
fi
done
}
main $1
(3)定时任务:
[root@db01 scripts]# crontab -l
*/3 * * * * /bin/sh /server/scripts/dosprotedted.sh /server/scripts/access_log >/dev/null 2>&1 #可以换作web服务的时间访问日志;
00 00 * * * /bin/sh /server/scripts/dosdelip.sh >/dev/null 2>&1 #每天凌晨放开前一天封闭的ip地址;
(4)测试:
1)防火墙命令;
iptables -F #清空所有的防火墙规则;
watch iptables -L -n #查看防火墙列表;
2)具体测试步骤:
在accesss_log日志中添加ip100个地址,会发现防火墙列表会多余对应的ip地址;
删除access_log日志中添加的ip地址,并改变当前的时间天数加一,会发现防火墙列表,对应的ip地址没有了;
3)守护进程的监控模式:
[root@db01 scripts]# vim dosprotedted.sh
#!/bin/sh
[ $UID -eq 0 ] ||{
echo "please use root user"
exit 1
}
function usage() {
echo "USAGE:sh $0 www_access.log"
exit 1
}
before_ipfile="/tmp/ip_$(date +%F -d '-1day').log"
function del() {
if [ -f $before_ipfile ]; then
exec <$before_ipfile
while read line; do
if [ `iptables -L -n | grep $line | wc -l` -ge 1 ];then
iptables -D INPUT -s $line -j DROP
fi
done
fi
}
tmpfile="/tmp/tmp.log"
now_ipfile="/tmp/ip_$(date +%F).log"
function main() {
if [ $# -eq 1 ]; then
awk '{print $1}' $1 | sort | uniq -c | sort -rn >$tmpfile
exec <$tmpfile
while read line; do
ip=`echo $line | awk '{print $2}'`
num=`echo $line | awk '{print $1}'`
if [ "$ip" != " " -a $ip != "::1" ]; then
if [ $num -gt 100 -a `iptables -L -n | grep $ip | wc -l` -lt 1 ]; then
iptables -I INPUT -s $ip -j DROP
if [ ! -f $now_ipfile ];then
touch $now_ipfile
fi
if [ `cat $now_ipfile | grep $ip | wc -l` -lt 1 ]; then
echo $ip >>$now_ipfile
fi
fi
fi
done
else
usage
fi
}
while true; do
main $*
sleep 180
del
done
21、开发专业监控mysql主从复制故障:
(1)编写代码:
1)代码1:
[root@db01 scripts]# vim myslave.sh
#!/bin/sh
export PATH=/application/mysql/bin/:/application/mysql/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
MYUSER="root"
MYPASS="123456"
MYCMD="mysql -u$MYUSER -p$MYPASS"
tmpfile="/tmp/mysqlstatus.txt"
status=(`$MYCMD -e "show slave status\G" | egrep "Seconds_Behind|_Running" | awk '{print $NF}'`)
[ "${status[0]}" = "yes" -a "${status[1]}" = "yes" -a "${status[2]}" = "0" ] || {
echo "mysql slave is fail" >$tmpfile
mail -s "$(date +%F\ %T) mysql slave status" hyjy2504164765@163.com <$tmpfile
}
2)代码2(略过同步错误,如果mysql配置文件中不存在此设置):
[root@db01 scripts]# cat myslave.sh
#!/bin/sh
export PATH=/application/mysql/bin/:/application/mysql/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
MYUSER="root"
MYPASS="123456"
MYCMD="mysql -u$MYUSER -p$MYPASS"
tmpfile="/tmp/mysqlstatus.txt"
erron=(1158 1159 1008 1007 1062)
status=(`$MYCMD -e "show slave status\G" | egrep "Seconds_Behind|_Running|Last_SQL_Errno" | awk '{print $NF}'`)
[ "${status[0]}" = "yes" -a "${status[1]}" = "yes" -a "${status[2]}" = "0" ] || {
for ((i=0;i<${#erron[*]};i++));do
if [ "${erron[i]}" = "${status[3]}" ]; then
$MYCMD -e "stop slave;"
$MYCMD -e "set global sql_slave_skip_counter = 1"
$MYCMD -e "start slave;"
break
fi
done
sleep 3
status=(`$MYCMD -e "show slave status\G" | egrep "Seconds_Behind|_Running|Last_SQL_Errno" | awk '{print $NF}'`)
[ "${status[0]}" = "yes" -a "${status[1]}" = "yes" -a "${status[2]}" = "0" ] || {
echo "mysql slave is fail" >$tmpfile
mail -s "$(date +%F\ %T) mysql slave status" hyjy2504164765@163.com <$tmpfile
}
}
A、设置参数:
将/etc/mysql.cnf之中的sql_slave_skip_counter的参数注释掉;
(2)设置邮件服务:
vim /etc/mail.rc
set from=hyjy2504164765@163.com smtp=smtp.163.com smtp-auth-user=hyjy2504164765 smtp-auth-password=linux123 smtp-auth=login #163邮箱
(3)设置定时任务:
[root@db01 scripts]# crontab -l
*/10 * * * * /bin/sh /server/scripts/myslave.sh >/dev/null 2>&1
22、中企动力面试题:
The months of learning in Old Boy education are the few months that I think the time efficient is the most.I had also studied at other training institutions before, but I was hard to understand what the tutor said and hard to follow. It was just too much to learn with no outline.
(1)按单词出现频率降序排序!
[root@db01 scripts]# sed "s#[,.]##g" sort.log | tr " " "\n" | awk '{S[$1]++} END {for(k in S) print S[k],k}' | sort -rn | head -5
4 the
3 to
2 was
2 months
2 I
[root@db01 scripts]# sed "s#[,.]##g" sort.log | tr " " "\n" | sort | uniq -c | sort -rn | head -5
4 the
3 to
2 was
2 months
2 I
(2)按字母出现频率降序排序!
[root@db01 scripts]# sed 's#[,. ]##g' sort.log | grep -o "." | awk '{S[$1]++} END {for (i in S) print S[i],i}' | sort -rn | head -5
33 t
20 o
19 e
18 n
17 i
[root@db01 scripts]# sed 's#[,. ]##g' sort.log | grep -o "." | sort | uniq -c | sort -rn | head -5
33 t
20 o
19 e
18 n
17 i
(3)扩展:去单词的方法:
[root@db01 scripts]# sed "s#[,. ]##g" sort.log | sed -r "s#(.)#\1\n#g"
23、根据输入的数字打印图形:
(1)代码
[root@backup scripts]# cat tuxing.sh
#!/bin/sh
function isnum() {
expr $1 + 1 &>/dev/null
if [ $? -ne 0 -a "$1" != "-1" ]; then
return 1
fi
return 0
}
function usage (){
echo "USAGE:sh $0 number"
exit 1
}
function show (){
num=$1
for ((i=1;i<=$num;i++)); do
echo -e "\n"
for ((j=$(($num-$i));j>0;j--)); do
echo -n " "
done
for ((n=1;n<=$((2*$i-1));n++)); do
echo -n "*"
done
done
echo -e "\n"
}
function main() {
if [ $# -eq 1 ]; then
isnum $1 && show $1 || usage
else
usage
fi
}
main $*
(2)测试:
[root@backup scripts]# sh tuxing.sh 5
*
***
*****
*******
*********
24、使用for循环在/lc目录下通过随机小写10个字母加固定字符串lc批量创建
10个html文件:
(1)实现随机数的方法:
[root@backup scripts]# echo $RADOM | md5sum | tr "[0-9]" "[a-z]" | cut -c 2-11
ibdcjdajij
(2)代码:
[root@backup scripts]# cat randomnum.sh
#!/bin/sh
mkdir -p /lc
for n in {1..10}; do
radom=`echo $RANDOM | md5sum | tr "[0-9]" "[a-z]" | cut -c 2-11`
touch "/lc/${radom}_.html"
done
(3)测试:
[root@backup scripts]# sh -x randomnum.sh
[root@backup scripts]# ls /lc/
abfbdgefca_.html dachdfjjeg_.html eagcefibeg_.html fifccadaib_.html hdccaceefa_.html
aejicacchf_.html dcfdedbjgf_.html edafaeefba_.html gfafafajde_.html jdhhabcfed_.html
25、写一个脚本,实现判断10.0.0.0/24网络里,当前在线用户的ip有哪些;
(1)监听在线的ip的方法有很多,其中有ping,telnet,nmap等命令,但主要分为两大类;
ping ip;扫描端口;
(2)代码:
1):ping模式;
速度慢
[root@backup scripts]# vim alive.sh
#!/bin/sh
. /etc/init.d/functions
CMD="ping -c 2 -W 2" #-c:返回2个ttl值;-W :超时时间为2秒;
IP="10.0.0."
for n in {1..254}; do
$CMD $IP$n &>/dev/null
if [ $? -eq 0 ]; then
action $IP$n /bin/true
fi
done
2)nmap模式:
#!/bin/sh
CMD="nmap -sP"
IP="10.0.0.0/24"
for n in {1..254}; do
$CMD $IP | grep "Nmap scan report for" | awk -F "[ ()]+" '{print $5}'
done
(3)网络扫描知识补充:
1)扫描指定网段当前所有在线主机开放的端口号:
[root@backup scripts]# nmap -sS 10.0.0.0/24
Starting Nmap 5.51 ( http://nmap.org ) at 2019-01-29 00:36 CST
Nmap scan report for 10.0.0.41
Host is up (0.000015s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
111/tcp open rpcbind
873/tcp open rsync
Nmap scan report for 10.0.0.253
Host is up (0.00024s latency).
All 1000 scanned ports on 10.0.0.253 are closed
MAC Address: 00:50:56:FC:EF:96 (VMware)
Nmap scan report for 10.0.0.254
Host is up (0.0012s latency).
Not shown: 993 filtered ports
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn
443/tcp open https
445/tcp open microsoft-ds
902/tcp open iss-realsecure
912/tcp open apex-mesh
3306/tcp open mysql
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap done: 256 IP addresses (3 hosts up) scanned in 36.91 seconds
2)扫描指定网段当前在线的所有主机:
[root@backup scripts]# nmap -sP 10.0.0.0/24
Starting Nmap 5.51 ( http://nmap.org ) at 2019-01-29 00:39 CST
Nmap scan report for 10.0.0.41
Host is up.
Nmap scan report for 10.0.0.253
Host is up (0.00027s latency).
MAC Address: 00:50:56:FC:EF:96 (VMware)
Nmap scan report for 10.0.0.254
Host is up (0.00055s latency).
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap done: 256 IP addresses (3 hosts up) scanned in 31.73 seconds
3)扫描指定ip地址主机开放的端口范围:
[root@backup scripts]# nc -w 1 10.0.0.41 -z 1-1000
Connection to 10.0.0.41 111 port [tcp/sunrpc] succeeded!
Connection to 10.0.0.41 873 port [tcp/rsync] succeeded!
26、开发shell脚本实现抓阄功能:
(1)开发要求:
执行脚本后,想去的通讯输入英文名字全拼,产生随机数01-99之间的数字,数字越大就去参加项目
实践,经抓到的数字,下次不能再出现相同的数字;
第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出要继续等待别的学生输入;
(2)代码:
expr $RANDOM % 99 #此代码代表0-98,random的范围是0-32767;
[root@backup scripts]# cat zhuajiu.sh
#!/bin/sh
log=/tmp/zhuajiu.log
[ -f $log ] || touch $log
while true; do
read -p "please input your English name:" name
if [ -z $name ]; then
continue
else
ran_num=`expr $RANDOM % 99 + 1`
zhua_num=`grep "\<$ran_num\>" $log | awk '{print $NF}'`
if [ -z "$zhua_num" ]; then
echo "$name $ran_num"
echo "$name $ran_num" >>$log
fi
fi
done
(3)测试:
[root@backup scripts]# sh zhuajiu.sh
please input your English name:lc
lc 39
please input your English name:liuc
liuc 65
please input your English name:^C
[root@backup scripts]# cat /tmp/zhuajiu.log
lc 39
liuc 65
27、开发shell脚本监控网站是否被挂马企业案例:
(1)实验数据:
[root@backup scripts]# mkdir -p www
[root@backup scripts]# touch /server/scripts/www/file_{1..10}.txt
[root@backup scripts]# ls www
file_10.txt file_2.txt file_4.txt file_6.txt file_8.txt
file_1.txt file_3.txt file_5.txt file_7.txt file_9.txt
(2)代码:
[root@backup ~]# vim /etc/mail.rc #配置邮件服务
set from=hyjy2504164765@163.com smtp=smtp.163.com smtp-auth-user=hyjy2504164765 smtp-auth-password=linux123 smtp-auth=login
[root@backup scripts]# cat NoHangHorse.sh
#/bin/sh
LANG=en
web_path="/server/scripts/www"
check_dir="/check/server_scripts_www"
mkdir -p $check_dir
old_md5_log="$check_dir/old_md5.log"
old_file_log="$check_dir/old_file.log"
find $web_path -type f >$old_file_log
find $web_path -type f | xargs md5sum >$old_md5_log
old_file_count=`cat $old_file_log | wc -l`
new_file_log=$check_dir/new_file.log
check_log=$check_dir/check_$(date +%F).log
while true; do
find $check_dir -type f -name "check*.log" -mtime +7 | xargs rm -f &>/dev/null
find $web_path -type f >$new_file_log
error_md5_count=`md5sum -c $old_md5_log 2>/dev/null | grep FAILED | wc -l`
new_file_count=`find $web_path -type f | wc -l`
if [ $error_md5_count -ne 0 -o $new_file_count -ne $old_file_count ]; then
echo "`md5sum -c $old_md5_log 2>/dev/null | grep FAILED`" >$check_log
diff $old_file_log $new_file_log >>$check_log
mail -s "web site is misrepresent $(date +%F\ %T)" hyjy2504164765@163.com <$check_log
fi
sleep 600
done
1)使用定时任务的方法:
单独执行带颜色的代码生成原始的效验文件,删除生成文件的语句(紫色部分)和while true语句,然后设置定时任务,
两者的效果是一致的;
(3)测试:
[root@backup scripts]# ls /check/server_scripts_www/
check_2019-02-12.log new_file.log old_file.log old_md5.log
[root@backup scripts]# sh NoHangHorse.sh &
[root@backup scripts]# jobs
[1]+ Running sh NoHangHorse.sh &
[root@backup scripts]# cd www
[root@backup www]# touch test.txt
[root@backup www]# vim file_10.txt
123
邮箱文件:
手机扫一扫
移动阅读更方便
你可能感兴趣的文章