shell案例

(案例一)

请按照这样的日期格式(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位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。
提示:

  1. 随机密码使用命令 mkpasswd
  2. 在脚本中给用户设置密码,可以使用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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值