1. 创作目的
为了加强和巩固自身对linux shell脚本的熟悉程度,通过100道练习题强化shell能力,同时分享自己的劳动成果给很多需要提升脚本能力的朋友,大家一起共同进步;
2. 练习题100道合集
2.1 练习题001
【题目要求】
请生成日期格式为yyyy-MM-dd的日志文件,每日生成一个文件, 例如生成的文件名为2024-04-28.log, 并且把磁盘的使用情况写到到这个文件中,同时将文件放到指定目录中,并删除一年前的日志记录; 不用考虑cron,仅仅写脚本即可
2.1.1 知识巩固
Date的用法
#打印当前时间
[root@kdc-server shell]# date
Sun Apr 28 02:51:21 CST 2024
#打印当年年份最后两位
[root@kdc-server shell]# date +%y
24
#打印当前完整年份
[root@kdc-server shell]# date +%Y
2024
#打印当月月份
[root@kdc-server shell]# date +%m
04
#打印当前小时数
[root@kdc-server shell]# date +%H
02
#打印当前秒数
[root@kdc-server shell]# date +%s
1714243745
#打印当前分钟的第几秒
[root@kdc-server shell]# date +%S
11
#打印一个星期的第几天,这里是0,表示星期天[0-6]
[root@kdc-server shell]# date +%w
0
#打印今年第几周
[root@kdc-server shell]# date +%W
17
#打印格式yyy-mm-dd的日期
[root@kdc-server shell]# date +%F
2024-04-28
#打印当前完整月份
[root@kdc-server shell]# date +%B
April
#打印当前月份缩写
[root@kdc-server shell]# date +%b
Apr
df命令的用法
[root@kdc-server ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 898M 0 898M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.7M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 2.0G 16G 12% /
/dev/sda1 1014M 151M 864M 15% /boot
cm_processes 910M 0 910M 0% /run/cloudera-scm-agent/process
tmpfs 182M 0 182M 0% /run/user/0
find命令的用法 后续补充
xargs命令用法 后续补充
-mtime命令用法 后续补充
2.1.2 脚本内容
#! /bin/bash
##生成yyyy-mm-dd格式的时间字符串
logname=`date +%F`
#指定日志存放的路径
dir=/opt/logs/disklog
#判断路径是否存在,不存在则创建
if [ ! -d $dir ]
then
mkdir -p $dir
fi
#将磁盘信息写入日志文件
df -h > $dir/$logname.log
#查询指定目录下修改时间在365天以前的文件,并执行删除
find $dir/ -mtime +365 | xargs rm -f
2.2 练习题002
【日志格式】
112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com “/seccode.php?update=0.5593110133088248″ 200″http://formula-x.haotui.com/registerbbs.php” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)”
61.147.76.51 – [25/Sep/2013:16:08:31 +0800]xyzdiy.5d6d.com “/attachment.php?aid=4554&k=9ce51e2c376bc861603c7689d97c04a1&t=1334564048&fid=9&sid=zgohwYoLZq2qPW233ZIRsJiUeu22XqE8f49jY9mouRSoE71″ 301″http://xyzdiy.5d6d.com/thread-1435-1-23.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)”
2.2.1 知识巩固
awk的用法
可以处理带空格的行数据
awk的使用格式
awk ‘条件1{执行语句1}条件2{执行语句2}条件3{执行语句3}’ filename 条件语句可选(文件名可选)
awk ‘BEGIN{执行语句1}{执行语句2}END{执行语句3}’ filename BEGIN和END条件语句可选(文件名可选)
#打印磁盘的使用信息
[root@kdc-server ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 898M 0 898M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.6M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 2.0G 16G 12% /
/dev/sda1 1014M 151M 864M 15% /boot
cm_processes 910M 0 910M 0% /run/cloudera-scm-agent/process
tmpfs 182M 0 182M 0% /run/user/0
#打印第二列和第五列的信息
[root@kdc-server ~]# df -h |awk '{printf $2 "\t" $5 "\n"}'
Size Use%
898M 0%
910M 0%
910M 2%
910M 0%
17G 12%
1014M 15%
910M 0%
182M 0%
#打印目录的信息
[root@kdc-server ~]# awk '{print $NF}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
Management:/:/sbin/nologin
bus:/:/sbin/nologin
polkitd:/:/sbin/nologin
SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
carlos:x:1000:1000:carlos:/home/carlos:/bin/bash
Manager:/var/lib/cloudera-scm-server:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
Daemon:/var/lib/rpcbind:/sbin/nologin
#以:为分隔符,打印目录的信息
[root@kdc-server ~]# awk 'BEGIN{FS=":"}{print $NF}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
[root@kdc-server ~]# awk '{print $NF}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
Management:/:/sbin/nologin
bus:/:/sbin/nologin
polkitd:/:/sbin/nologin
SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
carlos:x:1000:1000:carlos:/home/carlos:/bin/bash
Manager:/var/lib/cloudera-scm-server:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
Daemon:/var/lib/rpcbind:/sbin/nologin
#以:为分隔符,打印目录的信息,并去重统计
[root@kdc-server ~]# awk 'BEGIN{FS=":"}{print $NF}' /etc/passwd | uniq -c
1 /bin/bash
4 /sbin/nologin
1 /bin/sync
1 /sbin/shutdown
1 /sbin/halt
11 /sbin/nologin
1 /bin/bash
3 /sbin/nologin
2.2.2 脚本内容
#打印1.log日志中第一个参数,即IP地址;
#排序,去重统计出现的次数,即访问数量;
#再次逆序排序,可以查看在最前方统计次数的排序结果
awk '{print $1}' 1.log|sort |uniq -c |sort -n -r
2.3 练习题003
写一个脚本计算一下linux系统所有进程占用内存大小的和。
- ps命令用法
- for循环
- 加法运算
2.3.1 知识巩固
ps的用法
#显示内存信息(截取部分内容),RSS即内存占用大小
[root@kdc-server ~]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 128008 6664 ? Ss 13:04 0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 13:04 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 13:04 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? S 13:04 0:03 [ksoftirqd/0]
root 7 0.0 0.0 0 0 ? S 13:04 0:00 [migration/0]
root 8 0.0 0.0 0 0 ? S 13:04 0:00 [rcu_bh]
root 9 0.0 0.0 0 0 ? S 13:04 0:07 [rcu_sched]
root 10 0.0 0.0 0 0 ? S< 13:04 0:00 [lru-add-drain]
root 11 0.0 0.0 0 0 ? S 13:04 0:01 [watchdog/0]
root 12 0.0 0.0 0 0 ? S 13:04 0:01 [watchdog/1]
root 13 0.0 0.0 0 0 ? S 13:04 0:00 [migration/1]
for循环用法
for n in 范围
do
表达式
done
free的用法
[root@kdc-server shell]# free
total used free shared buff/cache available
Mem: 1863032 344296 1332812 9848 185924 1362948
Swap: 2097148 0 2097148
2.3.2 脚本内容
#! /bin/bash
sum=0
for n in `ps aux | grep -v 'TIME COMMAND' | awk '{print $6}t'`
do
sum=$[$sum+$n]
done
echo $sum
2.4 备份数据库
题目要求
设计一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝一份,本地保存一周的数据,远程保存一个月。假定,我们知道mysql root账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql, 远程服务器ip为192.168.123.30, 远程提供了一个rsync服务,备份的地址是 192.168.123.30::backup . 写完脚本后,需要加入到cron中,每天凌晨3点执行。
核心要点
备份数据库的命令
同步到远程去的命令
本地一周,可以用date +%w做为后缀,远程一个月可以用date +%d做为后缀
2.4.1 知识巩固
#打印时间
[root@kdc-server shell]# date +%F
2024-05-01
#打印一周的第几天[0-6]
[root@kdc-server shell]# date +%w
3
#打印一个月的第几天
[root@kdc-server shell]# date +%d
01
#mysql备份脚本语法
mysqldump -u username -p dbname [tbname ...]> filename.sql
#恢复脚本
mysql -u root -p < C:\all.sql
#从本地同步远程
# 默认SSH端口
rsync -avz -e ssh /home/bear/mydir [email protected]:/home/bear/workdir
# 指定SSH端口
rsync -avz -e 'ssh -p 5555' /home/bear/mydir [email protected]:/home/bear/workdir
#从远程同步到本地
# 默认SSH端口
rsync -avzP -e ssh [email protected]:/home/bear/workdir /home/bear/mydir
# 指定SSH端口
rsync -avzP -e 'ssh -p 5555' [email protected]:/home/bear/workdir /home/bear/mydir
2.4.2 脚本内容
#! /bin/bash
#打印本周星期几[0-6]
d1=`date +%w`
#打印本月的天数[0-31]
d2=`date +%d`
local_dir=/bak/mysql
remote_dir=192.168.123.30::backup
#mysql备份数据库脚本到本地
mysqldump -uroot -proot discuz > $local_dir/discuz.sql.$d1
#同步到远程
rsync -az $local_dir/discuz.sql.$d1 $remote_bakdir/discuz.sql.$d2
2.5 监控502
题目要求
服务器上跑的是LNMP环境,近期总是有502现象。502为网站访问的状态码,200正常,502错误是nginx最为普遍的错误状态码。由于502只是暂时的,并且只要一重启php-fpm服务则502消失,但不重启的话,则会一直持续很长时间。
所以有必要写一个监控脚本,监控访问日志的状态码,一旦发生502,则自动重启一下php-fpm。
我们设定:
1)access_log /data/log/access.log
2)脚本死循环,每10s检测一次(假设每10s钟的日志条数为300左右)
3)重启php-fpm的方法是 /etc/init.d/php-fpm restart
核心要点
用curl检测状态码是否是502或者通过分析访问日志判断状态码的比率
重启php-fpm服务的命令
2.5.1 知识巩固
#grep的用法
grep [options] pattern [files]
pattern - 表示要查找的字符串或正则表达式。
files - 表示要查找的文件名,可以同时查找多个文件,如果省略 files 参数,则默认从标准输入中读取数据。
-i:忽略大小写进行匹配。
-v:反向查找,只打印不匹配的行。
-n:显示匹配行的行号。
-r:递归查找子目录中的文件。
-l:只打印匹配的文件名。
-c:只打印匹配的行数。
[root@kdc-server shell]# echo "hello world" | grep -c world
1
#在文本中匹配带有error的日志
[root@kdc-server shell]# grep -i error app.log
#结合tail命令实时查看error日志
[root@kdc-server shell]# tail -f app.log | grep -i error
[root@kdc-server shell]# tail -f app.log | grep -A 9 -i error
-A 9: (after)匹配日志后的后9行日志
-B 9: (before)匹配日志后的前9行日志
-C 9: 匹配日志后的前后9行日志
#wc的用法
wc (word count)命令常用于计算文件的行数、字数和字节数
-l , --lines : 显示行数;
-w , --words : 显示字数;
-m , --chars : 显示字符数;
-c , --bytes : 显示字节数;
-L , --max-line-length : 显示最长行的长度
[root@kdc-server shell]# wc -l /root/shell/sh_008.sh
25 /root/shell/sh_008.sh
[root@kdc-server shell]# wc /root/shell/sh_008.sh
25 59 430 /root/shell/sh_008.sh
[root@kdc-server shell]# wc -w /root/shell/sh_008.sh
59 /root/shell/sh_008.sh
[root@kdc-server shell]# wc -m /root/shell/sh_008.sh
422 /root/shell/sh_008.sh
[root@kdc-server shell]# wc -L /root/shell/sh_008.sh
80 /root/shell/sh_008.sh
2.5.2 脚本内容
#! /bin/bash
#日志存储的位置
log=/data/log/access.log
while :
do
#从日志中最后300行找到502出现的次数,防止有些数字也有502 需要在前后加上空格
502_n=`tail -n 300 $log | grep -c ' 502 '`
#判断502状态码是否为空
if [ -z "$502_n"]
then
exit
fi
#判断502出现次数是否大于100
if [$502_n -gt 100 ]
then
#重启php,将错误日志写入指定文件
/etc/init.d/php-fpm restart >/dev/null 2>/tmp/php-fpm.err
#查询进程是否已经启动
fpm_p_n = `pgrep -l php-fpm |wc -l`
#判断进程出现的次数,如果为0就是启动失败
if [ $fpm_p_n -eq 0 ]
then
#发送邮件
python mail.py [email protected] "php.fpm重启失败" "`head -tmp/php-fpm.err`"
exit
fi
fi
#暂停10秒,每10秒监控一次
sleep 10
done
2.6 删除行
把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉。
2.6.1 内容回顾
#sed的用法
# 将第3行中所有的 bin 替换成 BIN
[root@kdc-server shell]# sed '3 s/bin/BIN/g' /etc/passwd
# 将第2到5行中所有的 bin 替换成 BIN
[root@kdc-server shell]#sed '2,5 s/bin/BIN/g' /etc/passwd
# 将第10行到最后一行中所有的 bin 替换成 BIN
[root@kdc-server shell]#sed '10,$ s/bin/BIN/g' /etc/passwd
2.6.2 脚本内容
#!/bin/bash
#打印前五行,并删除含中带字母的行
sed -n '1,5'p 1.txt |sed '/[a-zA-Z]/d'
#删除前面5行,原来的6-10变成了1-5;在匹配带字母的内容替换成空;
sed '1,5d' 1.txt |sed '1,5s/[a-zA-Z]//g'
版权归原作者 不做梦的Carlos 所有, 如有侵权,请联系我们删除。