(案例一)
请按照这样的日期格式(xxxx-xx-xx)每日生成一个文件,
例如生成的文件名为2017-12-20.log,
并且把磁盘的使用情况写到到这个文件中,
不用考虑cron,仅仅写脚本即可
分析
日期格式:(xxxx-xx-xx) 对应命令:date +%F
使用重定向将磁盘使用情况写入生成的文件中
代码展示
#!/bin/bash
d=`date +%F`
logfile=/tmp/$d.log
df -h>>$logfile
(案例二)
有日志1.log,部分内容如下
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)”
统计出每个IP访问量有多少
分析
统计每个IP的访问量主要是查重。
`先排序,在查重,最后反向排序直观查看访问量。`
代码展示
#!/bin/bash
awk '{print $1}' /tmp/1.log|sort |uniq -c |sort -nr
(案例三)
写一个脚本计算一下linux系统所有进程占用内存大小的和。
分析
`ps -aux`各列的意思:
USER //用户名
%CPU //进程占用的CPU百分比
%MEM //占用内存的百分比
VSZ //该进程使用的虚拟內存量
RSS //该进程占用的固定內存量
STAT //进程的状态
START //该进程被触发启动时间
TIME //该进程实际使用CPU运行的时间
`使用for循环遍历`
对遍历出的数据求和
代码展示
#!/bin/bash
sum=0
for memo in `ps -aux|awk '{print $6}'|grep -v "RSS" `
do
sum=$[$sum+$memo]
done
echo "THE total is $sum"
(案例四)
监控远程的一台机器(假设ip为180.163.26.39)的存活状态,当发现宕机时发一封邮件给你自己。
分析
ping -c10 180.163.26.39 通过ping来判定对方是否在线,对方不在线时给自己发邮件。
ping -c5 180.163.26.39|grep 'packet' |awk -F '%' '{print $1}' |awk '{print $NF}':截取丢包率。
代码展示
mail.py脚本展示
import smtplib
from email.mime.text import MIMEText
import os,sys
def sendqqmail(username,password,mailfrom,mailto,subject,content):
mail_host = 'smtp.163.com'
# 163用户名
mail_user = username
# 密码(部分邮箱为授权码)
mail_pass = password
# 邮件发送方邮箱地址
sender = mailfrom
# 邮件接受方邮箱地址,注意需要[]包裹,这意味着你可以写多个邮件地址群发
receivers = [mailto]
# 设置email信息
# 邮件内容设置
message = MIMEText(content, 'plain', 'utf-8')
# 邮件主题
message['Subject'] = subject
# 发送方信息
message['From'] = mailfrom
# 接受方信息
message['To'] = mailto
# 登录并发送邮件
try:
smtpObj = smtplib.SMTP()
# 连接到服务器
smtpObj.connect(mail_host, 25)
# 登录到服务器
smtpObj.login(mail_user, mail_pass)
# 发送
smtpObj.sendmail(
sender, receivers, message.as_string())
# 退出
smtpObj.quit()
print('success')
except smtplib.SMTPException as e:
print('error', e) # 打印错误
if __name__ == "__main__":
to=sys.argv[1]
subject=sys.argv[2]
content=sys.argv[3]
# 邮箱账号 授权码 发送人邮箱
sendqqmail('123456','授权码','123456@163.com',to,subject,content)
代码展示
#!/bin/bash
m=123456789@qq.com
while :
do
n=`ping -c5 180.163.26.39|grep 'packet' |awk -F '%' '{print $1}' |awk '{print $NF}'`
if [ $n -eq 0 ]
then
echo "该主机在线"
else
echo "该主机不线"
python3 mail.py $m "机器宕机" "丢包率是$n%"
fi
sleep 30
done
(案例五)
找到/123目录下所有后缀名为.txt的文件
1. 批量修改.txt为.txt.bak
2. 把所有.bak文件打包压缩为123.tar.gz
3. 批量还原文件的名字,即把增加的.bak再删除
问题
tar: Removing leading '/' from member names
由于tar默认为相对路径,使用绝对路径的话就会这个报错,加-P解决
分析
`重点需要/123目录下的.txt文件的绝对路径。`
使用find查找目录123中的txt文件的绝对路径,将绝对路径输出到/tmp/txt.log中。
只需后续使用/tmp/txt.log进行操作。
`for循环遍历`
代码展示
#!/bin/bash
#使用find查找目录123中的txt文件的绝对路径,将绝对路径输出到/tmp/txt.log中,使用for循环遍历/tmp/txt.log,对遍历出的内容进行改名。
find /123/ -type f -name "*.txt" > /tmp/txt.log
for f in `cat /tmp/txt.log`
do
mv $f $f.bak
done
#使用for循环遍历/tmp/txt.log打印输出到/tmp/txt.bak.log中,使用tar命令将txt.bak.log中绝对路径打包。
for f in `cat /tmp/txt.log`
do
echo $f.bak
done > /tmp/txt.bak.log
tar -czvPf 123.tar.gz `cat /tmp/txt.bak.log |xargs `
for f in `cat /tmp/txt.log`
do
mv $f.bak $f
done
(案例六)
判断本机的80端口(假如服务为httpd)是否开启着,如果开启着什么都不做,如果发现端口不存在,那么重启一下httpd服务,并发邮件通知你自己。脚本写好后,可以每一分钟执行一次,也可以写一个死循环的脚本,30s检测一次。
分析
netstat -ntpl |grep ':80 '|wc -l 用于检测80端口。
代码展示
#!/bin/bash
m=1234578@qq.com
while true
do
d=`date +%F-%T`
n=`netstat -ntpl|grep 80|wc -l`
if [ $n -eq 0 ];then
/usr/bin/systemctl restart httpd 2>>/tmp/httpd.err
python3 mail.py $m "80端口关闭" "httpd服务已重启_$d"
echo "$d restart httpd success"
else
echo "$d 80 already exists" >/tmp/80.log
fi
sleep 30
done
(案例七)
一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝一份,本地保存一周的数据,远程保存一个月。
假定,我们知道mysql root账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql, 远程服务器ip为10.30.58.21
远程提供了一个rsync服务,备份的地址是 10.30.58.21::backup . 写完脚本后,需要加入到cron中,每天凌晨3点执行。
分析
date +%w:一周
date +%d:一个月
mysql本地备份命令:mysqldump
rsync在10.30.58.21主机相关配置。
代码展示
#!/bin/bash
xq=`date +%w`
yf=`date +%d`
bfdir=/opt/mysql
yc_dir=10.30.58.21::backup
exec 1>/tmp/mysql.log 2>/tmp/mysql.err
echo "mysql start at `date`"
mysqldump -uroot -p000000 discuz >$bfdir/discuz.sql.$xq
rsync -az $bfdir/discuz.sql.$xq $yc_dir/discuz.sql.$yf
echo "mysql backup end at `date`"
0 03 * * * cd /usr/local/sbin/ceshi;bash lianxi07.sh
(案例九)
把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉。
1.log文件
1111111111111111111
121212aaasdasdf
asdfasdfasdfasdfasdf
12121212aklsdfjaklsdfkjk
*****#)#((@#*@)1121212
root@gitlba-aming shell100
12aaasdas23asdfasdf
asdf;lkjas;lkdjfkl;ajsdf
asl;dkfjalskdjflkj2elkjwlkej23kijlkjasdf
laksjdflkjslkdjfslkdjflksjdf
21l3k2l3k2l3kjl2k3jl2k3j
askdjfklasjdflklkajlksdjfkl12323232323
asdklfjalksdf
asldkfjalksdjfalksdjfklasjdf2323
aslkdjflk2k3j2lk3jl2k3j
asdklfjalksjdflkj132
asdfkjalksdjf121adfavasdfads asldkfjalksdjf
lkjlkjlwkerlk2j3lk21j3lkjflkasjdlkj23lkj klaj d
分析
sed -n ''p 打印某些行
sed ' d' 删除某些行
sed s///g 替换字符
代码展示
#!/bin/bash
sed -n '1,5'p ~/1.txt |sed '/[a-zA-Z]/d'
sed '1,5d' ~/1.txt |sed '1,5s/[a-zA-Z]//g'
(案例十)
用shell打印下面这句话中字母数小于6的单词。
Bash also interprets a number of multi-character options.
分析
以 +-.为分隔符截取字符串。`其中 +表示:匹配1个或多个空格。`
使用NF:内置变量,表示当前记录字段个数;
wc -L:打印最长行的长度
代码展示
#!/bin/bash
c="Bash also interprets a number of multi-character options."
n=`echo $c|awk -F '[ +-.]' '{print NF}'`
for ((i=1;i<$n;i++))
do
l=`echo $c|awk -F '[ +-.]' -v j=$i '{print $ j}'|wc -L`
if [ $l -lt 6 ]
then
echo $c|awk -F '[ +-.]' -v j=$i '{print $j}'
fi
done
(案例十一)
脚本实现如下功能:
输入一个数字,然后运行对应的一个命令。
显示命令如下:
cmd meau 1 - date 2 - ls 3 - who 4 - pwd
当输入1时,会运行date, 输入2时运行ls, 以此类推。
分析
read -p定义用户输入
使用case做对用户输入的内容做判断
代码展示
#!/bin/bash
echo "*cmd meau**"
echo "1 - date "
echo "2 - ls"
echo "3 - who"
echo "4 - pwd"
read -p "please input a number:" n
case $n in
1)
date
;;
2)
ls
;;
3)
who
;;
4)
pwd
;;
*)
echo "---------please input 1-4-----------"
esac
(案例十二)
用shell脚本实现如下需求:
添加user_00 – user_09
10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。
提示:
- 随机密码使用命令 mkpasswd
- 在脚本中给用户设置密码,可以使用echo 然后管道passwd命令
分析
seq -w :输出同宽度的数字。
yum install -y expect:安装mkpasswd的包
mkpasswd:
-l //(密码的长度定义, 默认是 9)
-d //(数字个数, 默认是 2)
-c //(小写字符个数, 默认是 2)
-C //(大写字符个数, 默认是 2)
-s //(特殊字符个数, 默认是 1)
echo “新密码”|passwd --stdin 用户名 //其中 --stdin表示标准输入。
代码展示
#!/bin/bash
for i in `seq -w 00 09`
do
useradd user_$i
mm=`mkpasswd -l 10 -s 0`
echo "user_$i $mm" >>/tmp/user_pass.log
echo $mm|passwd --stdin user_$i
done
(案例十五)
请仔细查看如下几个数字的规律,并使用shell脚本输出后面的十个数字。
10 31 53 77 105 141 …….
分析
规律为:从第二个两个数的差开始,差值为前一个两个数的差加2的x次方;从第三个数开始,第n个数等于前一个数+差值。例如:第二个差值为:21+2的0次方,第三个差值:22+2的1次方。
代码展示
#!/bin/bash
x=10
y=21
for i in `seq 0 15`
do
echo $x
x=$[$x+$y]
z=$[2**$i]
y=$[$y+$z]
done
(案例十六)
写个shell,看看你的Linux系统中是否有自定义用户(普通用户),若是有,一共有几个?
分析
`先判断centos版本,确认版本后,根据uid判断用户类型。`
用户id判断:
超级用户:0
虚拟用户:(centos7 1-999)
(Centos6 1-499)
普通用户:(centos7 1000-65535)
(Centos6 500-65535)
代码展示
#!/bin/bash
v=`awk -F 'release ' '{print $2}' /etc/redhat-release |cut -d '.' -f1`
user()
{
if [ $1 -eq 0 ]
then
echo "系统没有自定义的用户"
else
echo "系统存在自定义用户,有$1个"
fi
}
case $v in
6)
n=`awk -F ':' '$3>=500' /etc/passwd|wc -l`
user $n
;;
7)
n=`awk -F ':' '$3>=1000' /etc/passwd|wc -l`
user $n
;;
*)
echo "脚本有错误。"
;;
esac
(案例十九)
shell脚本来看看你使用最多的命令是哪些,列出你最常用的命令top10
分析
root/.bash_history用于记录历史命令
查看root/.bash_history文件,`排序、查重、再反向排序、取最高的前十个`
代码展示
#!/bin/bash
cat ~/.bash_history|sort |uniq -c |sort -nr |head
(案例二十)
假如需要每小时都去执行一个脚本。在脚本中实现这样的功能,当时间是0点和12点时,需要将目录/data/log/下的文件全部清空,
注意只能清空文件内容而不能删除文件
。而其他时间只需要统计一下每个文件的大小,一个文件一行,输出到一个按日期和时间为名字的日志里
。
需要考虑/data/log/目录下的二级、三级、… 等子目录里面的文件。
分析
只清空文件内容 :使用重定向将空覆盖文件内容。
文件大小一行一个:使用重定向追加。
使用`du -sh`查看文件的大小
代码展示
#!/bin/bash
dir=/tmp/log_info
t=`date +%F-%R`
t1=`date +%H`
logdir=/data/log
[ -d $dir ] || mkdir $dir
if [ $t == "00" -o $t == "12" ]
then
for f in `find $logdir/ -type f`
do
> $f
done
else
for f in `find $logdir/ -type f`
do
du -sh $f >> $dir/"$t".log
done
fi
crontab设置
*/30 * * * * cd /usr/local/sbin/ceshi/; bash lianxi20.sh