shell编程案例-100
1 每日一文件
【题目要求】
- 请按照这样的日期格式(xxxx-xx-xx)每日生成一个文件, 例如生成的文件名为2017-12-20.log, 并且把磁盘的使用情况写到到这个文件中, 不用考虑cron,仅仅写脚本即可。
- 并将生成的文件放入指定目录中,比如/data/logs/disklog/
- 找到1年以前的文件并删除掉
【解析】
1,首先获取到当天的日期,把日期作为变量进行赋值,
2,然后定义一下目录的变量,检查是否存在,如果不存在就创建目录,使用if-then语句
3,然后将磁盘使用情况写到指定文件中,最后删除1年之前的文件
并将磁盘使用情况写入文件
#!/bin/bash
d=`date +%F`
dir=/data/logs/disklog
if [ !-d $dir ]
then
mkdir -p $dir
fi
df -h > $dir/$d.log
find $dir/ -mtime +365 |xargs rm -f
2 统计IP访问量
1,题目要求
有日志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访问量有多少?
参考答案:
解析:
核心要点:awk、sort、uniq命令
sort如果排序的对象是数字,我们可以加上-n,字符串的话不用加,Ip地址我们当作字符串来看,如果需要用uniq -c统计重复次数,必须先进行排序。
sort -n -r 对次数进行倒序排列,次数由大到小awk'
awk '{print $1}' 1.log|sort |uniq -c |sort -nr
3 统计所有进程占内存之和
题目要求
写一个脚本计算一下linux系统所有进程占用内存大小的和。
解析:
核心要点:
ps命令用法
for循环
加法运算
参考答案:
法一:
#!/bin/bash
sum=0
for n in `ps aux |grep -v 'TIME COMMAND' |awk '{print $6}'`
do
sum=$[$sum+$n]
done
echo $sum
法二:
#!/bin/bash
sum=0
for n in `ps aux |sed '1'd |awk '{print $6}'`
do
sum=$[$sum+$n]
done
echo $sum
法四:
ps aux --no-headers | awk '{sum+=$6} END {print sum}'
法五:
ps aux |awk '{if(NR>1){print $6}}'
//NR:行号,当前处理的文本行的行号
//NF:number of filed 当前行的字段的个数,(即当前行被分割成了几列),字段数量怕
4 检测机器存活
题目要求
设计一个脚本,监控远程的一台机器(假设ip为180.163.26.39)的存活状态,当发现宕机时发一封邮件给你自己。
核心要点
ping -c10 180.163.26.39 通过ping来判定对方是否在线
参考答案:
#!/bin/bash
n=`ping -c5 192.168.81.112 |grep 'packet' |awk -F '%' '{print $1}' |awk '{print $NF}'`
if [ -z "$n"]
then
echo "脚本有问题"mm
python mail.py $m "检测机器存活脚本$0有问题""获取变量的值为空"
exit
else
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n" ]
then
echo "脚本有问题"
python mail.py $m "检测机器存活脚本$0有问题" "获取的变量的值不是纯数字"
exit
fi
fi
if
m=123@qq.com
while :
do
if [ $n -ge 50 ]
then
python mail.py $m "机器宕机,丢包率是$n%"
fi
sleep 30
done
5 批量修改并打包文件
题目要求
找到/123目录下所有后缀名为.txt的文件
批量修改.txt为.txt.bak
把所有.bak文件打包压缩为123.tar.gz
批量还原文件的名字,即把增加的.bak再删除
参考答案:
#!/bin/bash
find /123/ -type f -name "*.txt" > /tmp/txt.list
for f in `cat /tmp/txt.list`
do
mv $f $f.bak
done
# find /123/ -type f -name "*.txt" |xargs -I {} {}.bak
# find /123/ -type f -name "*.txt" -exec mv {} {}.bak \;
for f in `cat /tmp/txt.list`
do
echo $f.bak
done > /tmp/txt.bak.list
tar -czvf 123.tar.gz `cat /tmp/txt.bak,list |xargs `
for f in `cat /tmp/txt'.list`
do
mv $f.bak $f
done
6 检测80端口是否存在
【题目要求】
写一个脚本,判断本机的80端口(假如服务为httpd)是否开启,如果开启什么都不做,如果发现端口不存在,那么重启一下httpd服务,并发邮件通知自己,脚本写好后,可以每分钟执行一次,也可以写一个死循环,30s检测一次。
参考解析
思路:使用while-do-done语句实现循环功能,嵌套两个if-then语句实现过滤,告警功能
知识点:netstat -lntp ,wc -l,pgrep -lo,/usr/local/apache2/bin/apachectl -k restart,python mail.py $m,内容
#!/bin/bash
m=123@123.com
while :
do
n=`netstat -lntp |grep ':80 '|wc -l`
if [ $n -eq 0 ]
then
/usr/local/apache2/bin/apachectl -k restart 2>/tmp/apache.err
python mail.py $m "80端口关闭" "已经重启httpd服务"
pn=`pgrep -l httpd|wc -l`
if [ $pn -eq 0 ]
then
python mail.py $m "httpd重启失败" "`head -1 /tmp/apache.err`"
fi
fi
sleep 30
done
7 备份数据库
【题目要求】
设计一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝一份。本地保存一周的数据,远程保存一个月。
假定,我们知道mysql root账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql,远程服务器ip为192.168.81.112,远程提供了一个rsync服务,备份的地址是192.168.81.112::backup,写完脚本后需要加入到cron中,每天凌晨3点执行。
核心要点
备份数据库的命令
同步到远程去的命令
本地一周,可以用date +%w做为后缀,远程一个月可以用date +%d做为后缀
#!/bin/bash
d1=`date +%w` //会产生一周7天的文件
d2=`date +%d` //会产生一个月的文件,重复文件自动覆盖
local_bakdir=/bak/mysql
remote_bakdir=192.168.123.30::backup
exec 1> /tmp/mysqlbak.log 2>/tmp/mysqlbak.err //定义正确与错误的输出日志
echo "mysql backup begin at `date`" //echo一个备份开始时间
mysqldump -uroot -pXXX discuz > $local_bakdir/discuz.sql.$d1
rsync -az $local_bakdir/discuz.sql.$d1 $remote_bakdir/discuz.sql.$d2 //-az,递归并压缩
echo "mysql backup end at `date`" //echo一个备份结束时间
8 检测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服务的命令
参考答案:
#!/bin/bash
log=/data/log/access.log //日志文件的路径
while:
do
502_n=`tail -n 300 $log |grep -c ' 502 '` //统计最后300行日志中502的次数
if [ -z "$502_n" ] //判断是否为空
then
exit //直接退出脚本
fi
if [ $502_n -gt 100 ]
then
/etc/init.d/php-fpm restart >/dev/null 2 >/tmp/php-fpm.err //正常输出写入空,错误写入错误日志
fpm_p_n=`pgrep -l php-fpm|wc -l` //统计pho-fpm的进程数
if [ $fpm_p_n -eq 0 ] //若为0
then
python mail.py xxx@xx.com "php-fpm重启失败" "`head -l /tmp/php-fpm.err`" //发送告警邮件
exit
fi
fi
sleep 10
done
9 删除字母和行
题目要求:
把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉。
核心要点:
sed命令
参考答案:
sed -n '1,5'p 1.txt |sed '/[a-zA-Z]/d'
sed '1,5d' 1.txt |sed '1,5s/[a-zA-Z]//g'
10 打印字母数小于6的单词
题目要求:
用shell打印下面这句话中字母数小于6的单词。 Bash also interprets a number of multi-character options.
核心要点:
for循环遍历所有单词
wc -L获取字符串长度
参考答案:
#!/bin/bash
c="Bash also interprets a number of multi-character options."
n=`echo $c|awk -F '[ +-.]' '{print NF}'` //以1个或多个空白字符或“-” “.”为分隔符,用来统计段数
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
11 输入数字执行命令
题目要求
写一个脚本实现如下功能: 输入一个数字,然后运行对应的一个命令。
显示命令如下:
cmd meau* 1 - date 2 - ls 3 - who 4 - pwd 当输入1时,会运行date, 输入2时运行ls, 以此类推。
核心要点
case判断
首先定义一个变量n,若为空则提示,退出;再定义一个非纯数字判断变量n1,若为非纯数字则提示退出,然后用case判断5种情况
参考答案
#!/bin/bash
echo "*cmd mena** 1 - date 2 - ls 3 -who 4 - pwd"
read -p "please input a number: " n
if [ -z "$n" ]
then
echo "请输入一个纯数字,范围1-4."
exit
fi
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "请输入一个纯数字,范围1-4."
exit
fi
case $n in
1)
date
;;
2)
ls
;;
3)
who
;;
4)
pwd
;;
*)
echo "请输入1-4的数字"
;;
esac
12 批量创建用户
题目要求
用shell脚本实现如下需求:
添加user_00 – user_09 10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。 提示:
随机密码使用命令 mkpasswd
在脚本中给用户设置密码,可以使用echo 然后管道passwd命令
核心要点
seq实现数字递增
mkpasswd产生随机字符
首先使用for循环遍历00到09数字,seq -w 用来产生数字,mkpasswd -l -s 产生密码
然后将用户 密码记录到文件中
参考答案
#!/bin/bash
for i in `seq -w 00 09` //-w:产生两位的数字
do
useradd user_$i
p=`mkpasswd -l 10 -s 0 `
echo "user_$i $p" >> /tmp/pass.tmp //将用户密码一一对应记录到文件中
echo $p |passwd --stdin user_$i //批量为用户设置密码,不需要输两遍密码确认,注意--stdin的使用
done
13 监控httpd进程
题目要求
在服务器上,写一个监控脚本,要求如下:
1,每隔10s去检测一次服务器上的httpd进程数,如果大于等于500的时候,就需要自动重启一下apache服务,并检测启动是否成功?
2,若没有正常启动还需再一次启动,最大不成功数超过5次则需要立即发邮件通知管理员,并且以后不需要再检测!
3,如果启动成功后,1分钟后再次检测httpd进程数,若正常则重复之前操作(每隔10s检测一次),若还是大于等于500,那放弃重启并需要发邮件给管理员,然后自动退出该脚本。假设其中发邮件脚本为之前使用的mail.py
核心要点
pgrep -l httpd或者ps -C httpd --no-heading检查进程
for循环5次计数器
参考答案
#!/bin/bash
check_service()
{
n=0
for i in `seq 1 5`
do
/usr/local/apache2/bin/apachectl restart 2>/tmp/apache.err
if [ $? -ne 0 ] //不等于0
then
n=$[$n+1]
else
break
fi
done
if [ $n -eq 5 ]
then
##下面的mail.py参考https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py
python mai.py "123@qq.com" "httpd service down" `cat /tmp/apache.err`
exit
fi
}
while true
do
t_n=`ps -C httpd --no-heading |wc -l`
if [ $t_n -ge 500 ]
then
/usr/local/apache2/bin/apachectl restart
if [ $? -ne 0 ]
then
check_service
fi
sleep 60
t_n=`ps -C httpd --no-heading |wc -l`
if [ $t_n -ge 500 ]
then
python mai.py "123@qq.com" "httpd service somth wrong" "the httpd process is busy."
exit
fi
fi
sleep 10
done
14 封ip
题目要求
需求: 根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉!并且每隔半小时把不再发起请求或者请求量很小的ip给解封。 假设:
一分钟内请求量高于100次的IP视为不正常请求。
访问日志路径为/data/logs/access_log。
日志演示:
核心要点
统计ip访问次数,排序
如何标记每隔半小时
iptables计数器是一个重要的判断指标
函数(封IP、解封IP)
定义两个函数,
一个block_ip函数:先定义一个一分钟之前的时间变量,然后使用egrep将一分钟以前的日志过滤出来,使用awk将ip地址过滤出来,排序,去重,排序,将大于100的IP地址过滤出来,并将其重定向到文本中,然后遍历其中的ip进行封禁
一个unblock_ip函数:我们以iptables -nvL中的请求数据包计数作为解封ip判断依据,若小于5则视为此ip恢复正常并对其解封
然后定义一个主脚本,每30分钟解封一次ip
参考答案:
#!/bin/bash
block_ip() //封ip函数
{
t1=`date -d "-1 min" +%Y:%H:%M` //定义上一分钟时间变量
log=/data/logs/access_log
egrep "$t1:[0-9]+" $log > /tmp/tmp_last_min.log //将一分钟以前的日志过滤出来
awk '{print $1}' /tmp/tmp_last_min.log |sort -n |uniq -c|sort -n |awk '$1>100 {print $2}' > /tmp/bad_ip.list
//对第一列的ip地址进行排序去重再排序,并将大于100的ip过滤出来
n=`wc -l /tmp/bad_ip.list|awk '{print $1}'` //计算bad_ip.list文件列表行数
if [ $n -ne 0 ] //如果不等于0
then
for ip in `cat /tmp/bad_ip.list` //遍历IP地址
do
iptables -I INPUT -s $ip -j REJECT //将其封掉
done
fi
}
unblock_ip()
{
iptables -nvL INPUT|sed '1d' |awk '$1<5 {print $8}' > /tmp/good_ip.list //将被封ip数据包请求数小于5视为正常ip,将其过滤出来重定向到文档中
n=`wc -l /tmp/good_ip.list|awk '{print $1}'` //计算可以放行ip列表的行数
if [ $n -ne 0 ] //如果不为空
then
for ip in `cat /tmp/good_ip.list` //遍历ip
do
iptables -D INPUT -s $ip -j REJECT //将禁用ip规则删除
done
fi
iptables -Z //清空规则链中的数据包计算器和字节计数器;
}
t=`date +%M`
if [ $t == "00" ] || [ $t == "30" ] //每30分钟解封一次ip
then
unblock_ip //先执行unblock函数
block_ip
else
block_ip
fi
15 算数字
题目要求
请仔细查看如下几个数字的规律,并使用shell脚本输出后面的十个数字。
10 31 53 77 105 141 …….
核心要点
计算两个数值之间的差值
参考答案
#!/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
16 查用户
题目要求:
写个shell,看看你的Linux系统中是否有自定义用户(普通用户),若是有,一共有几个?
核心要点:
Centos 6,uid>=500
Centos 7,uid>=1000
首先判断linux的版本(cat /etc/redhat-release),然后自定义统计自定义用户的行数
方法一:
#!/bin/bash
v=`awk -F 'release ' '{print $2}' /etc/redhat-release |cut -d '.' -f1`
case $v in
5|6)
n=`awk -F ':' '$3>=500' /etc/passwd |wc -l`
if [ $n -eq 0 ]
then
echo "系统没有自定义的用户"
else
echo "系统存在自定义用户,有$n个"
fi
;;
7)
n=`awk -F ':' '$3>=1000' /etc/passwd |wc -l`
if [ $n -eq 0 ]
then
echo "系统没有自定义的用户"
else
echo "系统存在自定义用户,有$n个"
fi
;;
*)
echo "脚本出错"
;;
esac
方法二:定义一个user函数,简化脚本
#!/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
5|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
17 检测磁盘并邮件告警
题目要求
写一个shell脚本,检测所有磁盘分区使用率和inode使用率并记录到以当天日期为命名的日志文件里,当发现某个分区容量或者inode使用量大于85%时,发邮件通知你自己。
思路:
首先定义日志文件目录变量,时间变量,邮箱地址变量,然后判断日志文件目录是否存在,若不存在则创建一个日志文件目录,然后将df,df -i 内容追加到日志中,此时完成需求1。
然后对df,df -i 进行过滤,将使用量大于85的行重定向到临时文件中,然后计算出临时文件中行数并打印出行数,然后定义一个tag变量,使用if-then结构对四种情况进行处理,然后使用case结构进行邮件相关操作
参考答案:
#!/bin/bash
dir=/tmp/disk
d=`date +%F` //以年-月-日显示日期
mail=123@123.com
[ -d $dir ] || mkdir $dir //判断目录是否存在,如果不存在就创建一个目录
df >> $dir/$d.log //
df -i >> $dir/$d.log //一定要写追加
df|sed '1d'|awk -F ' +|%' '$5>=85 {print $7}' > $dir/df.tmp //磁盘分区使用率若大于85就打印出分区名称
df -i |sed '1d'|awk -F ' +|%' '$5>=85 {print $7}' > $dir/df_i.tmp //
n1=`wc -l $dir/df.tmp|awk '{print $1}'` //打印出行数
n2=`wc -l $dir/df_i.tmp|awk '{print $1}'`
tag=0
if [ $n1 -gt 0 ]
then
if [ $n2 -gt 0 ]
then
tag=11
else
tag=10
fi
else
if [ $n2 -gt 0 ]
then
tag=01
else
tag=00
fi
fi
case $tag in
11)
python mail.py $mail "磁盘空间和inode使用率高于85%" "`cat $dir/df.tmp $dir/df_i.tmp|xargs`"
;;
10)
python mail.py $mail "磁盘空间使用率高于85%" "`cat $dir/df.tmp|xargs`"
;;
01)
python mail.py $mail "磁盘inode使用率高于85%" "`cat $dir/df_i.tmp|xargs`" //xargs目的是将文本写道一行
;;
*)
;;
esac
18 检测新文件
题目要求:
有一台服务器作为web应用,有一个目录(/data/web/attachment)不定时地会被用户上传新的文件,但是不知道什么时候会上传。所以,需要我们每5分钟做一次检测是否有新文件生成。请写一个shell脚本去完成检测。检测完成后若是有新文件,还需要将新文件的列表输出到一个按年、月、日、时、分为名字的日志里。
思路:
定义原目录,和时间变量,用find -mmin -5将5分钟内的文件重定向到临时文件列表中,然后计算文件列表行数,若大于0,则将临时文件列表改名为以时间标记的文件中
参考:
#!/bin/bash
basedir=/data/web/attachment
t=`date +%Y%m%d%H%M`
find $basedir/ -type f -mmin -5 > /tmp/file.list
n=`wc -l /tmp/file.list |awk '{print $1}'`
if [ $n -gt 0 ]
then
mv /tmp/file.list /tmp/$t.list
fi
19 列出最常用的10个命令
题目:
写一个shell脚本来看看你最常用命令是哪些,列出最常用的命令top 10
cat ~/.bash_history |sort |uniq -c |sort -nr |head
20 统计文件大小
题目:
假如需要每小时都去执行一个脚本,在脚本中实现这样的功能,当时间时0点和12点时,需要将目录/data/log/下的文件全部清空,注意只能清空文件内容而不能删除文件。而其它时间只需要统计一下每个文件的大小,一个文件一行,输出到一个按日期和时间为名字的日志里,需要考虑/data/log/目录下二级,三级...等子目录里面的文件。
参考:
#!bin/bash
dir=/tmp/log_stat
t=`date +%d%H`
t1=`date +%H`
logdir=/data/log
[ -d $dir ] || mkdir $dir
[ -f $dir/$t.log ] && rm -f $dir/$t.log
if [ $t1 == "00" -o $t1 =="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
21 计算数字个数
题目:
计算文档a.txt中每一行中出现的数字个数并且要计算一下整个文档中一共出现了几个数字。例如a.txt内容如下: 12aa*lkjskdj alskdflkskdjflkjj 我们脚本名字为 ncount.sh, 运行它时: bash ncount.sh a.txt 输出结果应该为: 2 0 sum:2
参考:
#!/bin/bash
sum=0
while read line
do
line_n=`echo $line|sed 's/[^0-9]//g'|wc-L`
echo $line_n
sum=$[$sum+$line_n]
done < $1
echo "sum:$sum"
22_对比文件差异
题目:
有两台linux服务器A和B,假如A可以直接ssh到B,不用输入密码。A和B都有一个目录叫做/data/web/这下面有很多文件,当然我们不知道具体由几层子目录,假若之前A和B上该目录下的文件都是一模一样的。
但现在不确定是否一致了。故需要我们写一个脚本实现这样的功能,检测A机器和B机器/data/web/目录下文件的异同,我们以A机器上的文件作为标准。
比如,假若B机器少了一个a.txt文件,那我们应该能检测出来,或者B机器上的b.txt文件有过改动,我们也应该能够检测出来(B机器上多个文件不应考虑)。
参考:
#!/bin/bash
dir=/data/web
[ -f /tmp/md5.list ] && rm -f /tmp/md5.list
find $dir/ -type f > /tmp/file.list
while read line
do
md5sum $line >> /tmp/md5.list
done < /tmp/file.list
scp /tmp/md5.list B:/tmp/
[ -f /tmp/check_md5.sh ] && rm -f /tmp/check_md5.sh
cat >/tmp/check_md5.sh << EOF
#!/bin/bash
dir=/data/web
n=\`wc -l /tmp/md5.list|awk '{print \$1}'\`
for i in \`seq 1 \$n\`
do
file_name=\`sed -n "\$i"p /tmp/md5.list |awk '{print \$1}'\`
md5=\`sed -n "\$i"p /tmp/md5.list|awk '{print \$2}'\`
if [ -f \$file_name ]
then
md5_b=\`md5sum \$file_name\`
if [\$md5_b != \$md5 ]
then
echo "\$file_name changed."
fi
else
echo "\$file_name lose."
fi
done
EOF
scp /tmp/check_md5.sh B:/tmp/
ssh B "/bin/bash /tmp/check_md5.sh"
题目要求
写一个脚本,检测你的网络流量,并记录到一个日志里。需要按照如下格式,并且一分钟统计一次(只需要统计外网网卡,假设网卡名字为eth0):
2017-08-04 01:11 eth0 input: 1000bps eth0 output : 200000bps
2017-08-04 01:12 eth0 input: 1000bps eth0 output : 200000bps
提示:使用sar -n DEV 1 59 这样可以统计一分钟的平均网卡流量,只需要最后面的平均值。另外,注意换算一下,1Byte=8bit
23 检测网卡流量
题目要求
写一个脚本,检测你的网络流量,并记录到一个日志里。需要按照如下格式,并且一分钟统计一次(只需要统计外网网卡,假设网卡名字为eth0):
2017-08-04 01:11 eth0 input: 1000bps eth0 output : 200000bps
2017-08-04 01:12 eth0 input: 1000bps eth0 output : 200000bps
提示:使用sar -n DEV 1 59 这样可以统计一分钟的平均网卡流量,只需要最后面的平均值。另外,注意换算一下,1Byte=8bit
参考答案
#!/bin/bash
logdir=/tmp/sar_log
file=$logdir/`date +%d%H`.log
t=`date +"%F %H:%M"`
[ -d $logdir ] || mkdir -p $logdir
LANG=en
sar -n DEV 1 5 |grep eth0 |grep "Average" > /tmp/sar.tmp
exec >>$file
echo "$t"
awk '{print "etho input:",$5*8000"bps""\n""eth0 output:",$6*8000"bps"}'
echo "#######################"
24 批量杀进程
题目要求
一台机器负载高,top查看有很多sh的进程,然后top -c查看可以看到对应的进程命令是sh -c /bin/clearnen.sh 。
经分析后发现是因为该脚本执行时间太长,导致后续执行时,上次的脚本还未执行结束。写一个脚本批量杀死所有sh的进程。
参考:
#!/bin/bash
for pid in `ps aux |grep clearnen.sh |awk '{print $2}'`
do
echo $pid
kill -9 $pid
done
25 判断是否开启了web服务
题目要求
写一个脚本判断你的Linux服务器里是否开启web服务?(监听80端口)如果开启了,请判断出跑的是什么服务,是httpd呢还是nginx又或者是其他的什么?
参考答案
#!/bin/bash
n=`netstat -lntp |grep ':80'|wc -l`
if [ $n -eq 0 ]
then
echo "it not listen port 80"
else
ser=`netstat -lntp |grep ':80'|awk -F '[/:]' '{print $4}'`
echo "it is listening port 80,and the service is $ser."
fi
26 监控mysql服务
题目要求
假设,当前MySQL服务的root密码为123456,写脚本检测MySQL服务是否正常(比如,可以正常进入mysql执行show processlist),
并检测一下当前的MySQL服务是主还是从,如果是从,请判断它的主从服务是否异常。如果是主,则不需要做什么。
参考答案
#!/bin/bash
mysql="/usr/local/mysql/bin/mysql -uroot -p123456"
if ! $mysql -e "show processlist" >/dev/null 2>/dev/null //看此命令是否成功执行,不关心输出什么内容
then
echo "MySQL service is down."
exit
else
$mysql -e "show slave status\G" 2>/dev/null >/tmp/slave.stat //判断是否有输出
n=`wc -l /tmp/slave.stat|awk '{print $1}'` //计算临时文件行数
if [ $n -eq 0 ]
then
echo "This is master."
else
echo "This is slave."
egrep 'Slave_IO_Running:|Slave_SQL_Running:'/tmp/slave.stat|awk -F ': ' '{print $2}' > /tmp/SQL.tmp //根据IO,SQL_Runnig判断从是否有问题
if grep -qw "No" /tmp/SQL.tmp //如果有一个是NO,则说明有问题
then
echo "The slave is down."
fi
fi
fi
注:
grep
-q 静默模式,不输出任何信息,当我们只关系有没有匹配到,却不关心匹配到什么内容的时候,我们可以使用此命令,然后,使用"echo $?"查看是否匹配到,0表示匹配到,1表示没有匹配到;
-w 匹配整个单词,如果是字符串中包含这个单词,则不作匹配;
27 增删用户
题目要求:
写一个支持选项的增加或删除用户的shell脚本,具体要求如下:
只支持三个选项:'--del','--add','--help',输入其他选项报错。
使用'--add'时,需要验证用户名是否存在,存在则反馈存在,且不添加。 不存在则创建该用户,需要设置与该用户名相同的密码。
使用'--del'时,需要验证用户名是否存在,存在则删除用户及其家目录。不存在则反馈该用户不存在。
--help选项反馈出使用方法。
能用echo $?检测脚本执行情况,成功删除或添加用户为0,不成功为非0正整数。
能以英文逗号分割,一次性添加或者删除多个用户。例如 adddel.sh --add user1,user2,user3
#!/bin/baash
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo "Wrong, use bash $0 --add username, or bash $0 --del username or bash $0 --help"
exit
fi
ex_user()
{
if ! id $1 2>/dev/null >/dev/null
then
useradd $1 && echo "$1 add successful."
else
echo $1 exist.
fi
}
notex_user()
{
if id $1 2>/dev/null >/dev/null
then
userdel $1 && echo "$1 delete successful."
else
echo $1 not exist.
fi
}
case $1 in
--add)
if [ $# -eq 1 ]
then
echo "Wrong, use bash $0 --add user or bash $0 --add user1,user2,user3..."
exit
else
n=`echo $2| awk -F ',' '{print NF}'`
if [ $n -gt 1 ]
then
for i in `seq 1 $n`
do
username=`echo $2 |awk -v j=$i -F ',' '{print $j}'`
ex_user $username
done
else
ex_user $2
fi
fi
;;
--del)
if [ $# -eq 1 ]
then
echo "Wrong, use bash $0 --del user or bash $0 --del user1,user2,user3..."
exit
else
n=`echo $2| awk -F ',' '{print NF}'`
if [ $n -gt 1 ]
then
for i in `seq 1 $n`
do
username=`echo $2 |awk -v j=$i -F ',' '{print $j}'`
notex_user $username
done
else
notex_user $2
fi
fi
;;
--help)
if [ $# -ne 1 ]
then
echo "Wrong, use bash $0 --help"
exit
else
echo "Use bash $0 --add username or bash $0 --add user1,user2,user3... add user."
echo " bash $0 --del username -r bash $0 --del user1,user2,user3... delete user."
echo " bash $0 --help print this info."
fi
;;
*)
echo "Wrong, use bash $0 --add username, or bash $0 --del username or bash $0 --help"
;;
esac
28 计算数字和
题目要求
写一个脚本: 计算100以内所有能被3整除的正整数的和
解析:
#!/bin/bash
sum=0
for i in `seq 1 100`
do
j=$[$i%3] //通过%进行取余操作,然后进行判断
if [ $j -eq 0 ]
then
sum=$[$sum+$i]
fi
done
echo $sum
29 加减乘除
题目要求
使用传参的方法写个脚本,实现加减乘除的功能。 例如: sh a.sh 1 2,这样会分别计算加、减、乘、除的结果。
要求:
脚本需判断提供的两个数字必须为整数
当做减法或者除法时,需要判断哪个数字大,减法时需要用大的数字减小的数字,除法时需要用大的数字除以小的数字,并且结果需要保留两个小数点。
解析:
#!/bin/bash
is_nu()
{
n=`echo $1 |sed 's/[0-9]//g'`
if [ -n "$n" ]
then
echo "给出的参数必须是正整数"
exit
fi
}
if [ $# -ne 2 ]
then
echo "必须要输入两个参数"
exit
else
is_nu $1
is_nu $2
fi
big()
{
if [ $1 -gt $2 ]
then
echo $1
else
echo $2
fi
}
small()
{
if [ $1 -lt $2 ]
then
echo $1
else
echo $2
fi
}
add()
{
sum=$[$1+$2]
echo "$1+$2=$sum"
}
jian()
{
b=`big $1 $2`
s=`small $1 $2`
cha=$[$b-$s]
echo "$b-$s=$cha"
}
cheng()
{
ji=$[$1*$2]
echo "$1x$2=$ji"
}
chu()
{
b=`big $1 $2`
s=`small $1 $2`
v=`echo "scale=2;$b/$s"|bc`
echo "$b/$s=$v"
}
add $1 $2
jian $1 $2
cheng $1 $2
chu $1 $2
30 输入数字
题目要求
写一个脚本,执行后,打印一行提示“Please input a number:",要求用户输入数值,然后打印出该数值,然后再次要求用户输入数值。直到用户输入"end"停止。
#!/bin/bash
while :
do
read -p "Please input a number: " n
if [ -z "$n" ]
then
echo "请输入一个纯数字."
continue
fi
if echo $n |grep -qi 'end'
then
exit
fi
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "请输入一个纯数字."
continue
else
echo "你输入的数字是: $n"
continue
fi
done
31 获取网卡ip并显示颜色
题目要求
提示用户输入网卡的名字,然后我们用脚本输出网卡的ip,并要求输出的ip显示颜色,需要考虑下面问题:
输入的字符不符合网卡名字规范,怎么应对。
名字符合规范,但是根本就没有这个网卡又怎么应对。
[root@ser02:~]# cat net.sh
#!/bin/bash
ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' > /tmp/eth.list
while :
do
eths=`cat /tmp/eth.list|xargs`
read -p "Please input a if name(The eths is `echo -e "\033[31m$eths\033[0m"`): " eth
if [ -z "$eth" ]
then
echo "Please input a if name."
continue
fi
if ! grep -qw "$eth" /tmp/eth.list //-q 静默模式,-w 匹配整个单词
then
echo "The if name is error."
continue
else
break
fi
done
if_ip()
{
ip add show dev $1|grep ' inet '|awk '{print $2}'|awk -F '/' '{print $1}' >/tmp/$1.txt
n=`wc -l /tmp/$1.txt|awk '{print $1}'`
if [ $n -eq 0 ]
then
echo "There is no ip address on then eth."
else
echo "The ip address is:"
for ip in `cat /tmp/$1.txt`
do
echo -e "\033[33m$ip\033[0m"
done
fi
}
if_ip $eth
32 列出目录内容
题目要求
写一个脚本,实现如下功能:
脚本可以带参数也可以不带
参数可以有多个,每个参数必须是一个目录
脚本检查参数个数,若等于0,则列出当前目录本身,否则显示每个参数包含的子目录。
参考答案
#!/bin/bash
if [ $# -eq 0 ]
then
echo "当前目录下的文件是:"
ls .
else
for d in $@ //$@表示所有参数
do
if [ -d $d ]
then
echo "目录$d下有这些子目录:"
find $d -type d
else
echo "并没有目录:$d"
fi
done
fi
33 下载文件
题目要求
定义一个shell函数,能接受两个参数,满足以下要求:
第一个参数为URL,即可下载的文件,第二个参数为目录,即下载后保存的位置
如果用户给的目录不存在,则提示用户是否创建,如果创建就继续执行,否则,函数返回一个51的错误值给调用脚本
如果给的目录存在,则下载文件,下载命令执行结束后测试文件下载成功与否,如果成功,则返回0给调用脚本,否则,返回52给调用脚本
解析:
#!/bin/bash
if [ $# -ne 2 ]
then
echo "你必须输入两个参数,第一个参数是网址,第二个参数是目录."
exit 1
fi
if [ ! -d $2 ]
then
while :
do
echo "你输入的第二个参数,并不是一个存在的目录。是否要创建该目录呢?(y|n): "c
case $c in
y|Y)
mkdir -p $2
;;
n|N)
exit 51
;;
*)
echo "请输入y或者n."
continue
;;
esac
done
else
cd $2
wget $2
if [ $? -eq 0 ]
then
exit 0
else
echo "下载失败."
exit 52
fi
fi
34 猜数字
题目要求
写一个猜数字脚本,当用户输入的数字和预设数字(随机生成一个0-100的数字)一样时,直接退出,否则让用户一直输入,并且提示用户的数字比预设数字大或者小。
解析:
#!bin/bash
n=$[$RANDOM%101] //$RANDOM可以产生一个随机数字
while :
do
read -p "请输入一个0-100的数字:" n1
if [ -z "$n1" ]
then
echo "必须要输入一个数字"
continue
fi
n2=`echo $n1 |sed 's/[0-9]//g'`
if [ -n "$n2" ]
then
echo "你输入的数字并不是正整数."
continue
else
if [ $n -gt $1 ]
then
echo "你输入的数字小了,请重试"
continue
elif [ $n -lt $n1 ]
then
echo "你输入的数字大了,请重试。"
continue
else
echo "恭喜你,猜对了!"
break
fi
fi
done
35 根据名字得出数字
题目要求:
写一个shell脚本,能实现如下需求:
执行脚本后,提示输入名字(英文的,可以是大小写字母、数字不能有其他特殊符号),然后输出一个随机的0-99之间的数字,脚本并不会退出,继续提示让输入名字
如果输入相同的名字,输出的数字还是第一次输入该名字时输出的结果
前面已经输出过的数字,下次不能再出现
当输入q或者Q时,脚本会退出。
参考:
判断名字合法性[a-zA-Z0-9]
$RANDOM处以100取余得到0-99之间的随机数
#!/bin/bash
f=/tmp/user_number.txt
j_n()
{
while :
do
n=$[RANDOM%100]
if awk '{print $2}' $f|grep -qw $n
then
continue
else
break
fi
done
}
while :
do
read -p "Please input a username: " u
if [ -z "$u" ]
then
echo "请输入用户名."
continue
fi
if [ $u == "q" ] || [ $u == "Q" ]
then
exit
fi
u1=`echo $u|sed 's/[a-zA-Z0-9]//g'`
if [ -n "$u1" ]
then
echo "你输入的用户名不符合规范,正确的用户名应该是大小写字母和数字的组合"
continue
else
if [ -f $f ]
then
u_n=`awk -v uu=$u '$1==uu {print $2}' $f`
if [ -n "$u_n" ]
then
echo "用户$u对应的数字是:$u_n"
else
j_n
echo "用户$u对应的数字是:$n"
echo "$u $n" >>$f
fi
else
j_n
echo "用户$u对应的数字是:$n"
echo $u $n >> $f
fi
fi
done
36 一个数字的行
1,用shell实现,把一个文本文档中只有一个数字的行给打印出来。
核心要点:用sed替换所有非数字的字符为空,剩下的就是数字
#!/bin/bash
while read line //遍历文件所有的行
do
n=`echo $line|sed 's/[^0-9]//g'|wc -L //将所有非数字的字符替换为空,wc -L计算字符串长度
if [ $n -eq 1 ]
then
echo $line
fi
done < 1.txt //指定一个待操作的文件
37 日志切割分档
题目要求
系统logrotate工具,可以完成日志切割、归档。写一个shell脚本实现类似的归档功能。 举例: 假如服务的输出日志是1.log,要求每天归档一个,1.log第二天就变成1.log.1,第三天1.log.2, 第四天 1.log.3 一直到1.log.5。
#!/bin/bash
cd /data/logs
log=1.log
mv_log()
{
[ -f $1 ] && mv $1 $2
}
[ -f 1.log.5 ] && rm -f 1.log.5
for i in `seq 4 -1 1`
do
j=$[$i+1]
mv_log $log.$i $log.$j
done
mv 1.log 1.log.1
38 查找在线IP
题目:
写一个shell脚本,把192.168.0.0/24网段在线的ip列出来。
参考答案:
#!/bin/bash
for i in `seq 1 254`
do
if ping -c 2 -W 2 192.168.0.$i >/dev/null 2>/dev/null //-c ping的次数,-W 2 定义超时时间
then
echo "192.168.0.$i 是通的"
else
echo "192.168.0.$i 不通"
fi
done
39 检查脚本错误
题目:
写一个shell脚本,检查指定的shell脚本是否有语法错误,若有错误,首先显示错误信息,然后提示用户输入q或Q退出脚本,输入其它内容则直接用vim打开该shell脚本。
参考解析:
#!/bin/bash
sh -n $1 2>/tmp/sh.err
if [ $? -ne 0 ] //如果$?不等于0
then
cat /tmp/sh.err
read -p "请输入q/Q退出脚本。 " c //定义一个指令c
if [ -z "$c" ]
then
vim $1
exit 0
fi
if [ $c == q ] || [ $c == Q ]
then
exit 0
else
vim $1
exit 0
fi
else
echo 脚本$1没有语法错误"
fi
40 格式化数字
题目要求
输入一串随机数字,然后按千分位输出。 比如输入数字串为“123456789”,输出为123,456,789。
解析:
#!/bin/bash
n=`echo $1|wc -L`
for d in `echo $1|sed 's/./& /g'` //.代表每个数字,&代表前面的.
do
n2=$[$n%3] //判断是否能被3整除
if [ $n2 -eq 0 ]
then
echo -n ",$d" //echo -n 不换行输出,能被3整除就在前面加一个,
else
echo -n "$d"
fi
n=$[$n-1]
done |sed 's/^,//'
echo
41 问候脚本
题目要求
编写一个问候程序,它执行时能根据系统当前的时间向用户输出问候信息。假设从半夜到中午为早晨,中午到下午六点为下午,下午六点到半夜为晚上。
参考解析:
#!/bin/bash
d=`date +%H`
if [ $d -ge 0 -a $d -lt 7 ]
then
tag=1
elif [ $d -ge 7 -a $d -lt 12 ]
then
tag=2
elif [ $d -ge 12 -a $d -lt 18 ]
then
tag =3
else
tag=4
fi
case $tag in
1)
echo "早上好"
;;
2)
echo "上午好"
;;
3)
echo "下午好"
;;
4)
echo "晚上好"
;;
*)
echo "脚本出错啦"
;;
esac
42 菜单脚本
题目要求
写一个shell脚本,实现简单的弹出式菜单功能,用户能根据显示的菜单项从键盘选择执行对应的命令。
法1:select do done 循环体
#!/bin/bash
PS3="Please input your choice(1-4): "
select i in w ls pwd quit
do
case $i in
w)
w
;;
ls)
ls
;;
pwd)
pwd
;;
quit)
exit
;;
*)
echo "Please input 1-3."
;;
esac
done
法2:
#!/bin/bash
echo -e "1) w\n2) pwd\n4) quit"
while :
do
read -p "Please input your choice(1-4): " c
case $c in
1)
w
;;
2)
ls
;;
3)
pwd
;;
4 )
exit
;;
*)
echo "Please input 1-4."
;;
esac
done
43 检查用户是否登陆
题目要求:
写一个shell脚本,执行中每隔5分钟检查指定的用户是否登录系统,用户名从命令行输入,如果指定的用户已经登录,则显示相关信息。
思路:利用传参的形式,w命令进行
[root@ser03:~]# vim login.sh
#!/bin/bash
while :
do
if w|awk 'NR>2 {print $1}'|grep -qw "$1"
//首先过滤出来的第一列,看看能不能搜到传参参数$1,也就是用户名
then
echo "用户$1已经登录系统."
exit
fi
sleep 300
done
测试:
sh login.sh user1
44 检查系统是否被入侵
1,先普及一个小常识,我们用ps aux可以查看到进程的PID,而每个PID都会在/proc内产生。如果查看到的pid在proc内是没有的,则进程被人修改了,这就代表系统很有可能已经被入侵过了。 请用上面知识编写一个shell,定期检查下自己的系统是否被人入侵过
#!/bin/bash
pp=$$
ps -elf |sed '1'd>/tmp/pid.txt
for pid in `awk -v ppn=$pp '$5!=ppn {print $4}' /tmp/pid.txt`
do
if ! [ -d /proc/$pid ]
then
echo "系统中并没有pid为$pid的目录,需要检查"
fi
done
45 三行并一行
题目要求
想办法把文本里面每三行内容合并到一行 例如:1.txt内容
1
2
3
4
5
6
7
处理后应该是
1 2 3
4 5 6
7
思路:while read line逐行遍历,echo -n :不换行输出
参考答案
#!/bin/bash
n=1
cat $1 |while read line
do
n1=$[$n%3] //取余
if [ $n1 -eq 0 ]
then
echo "$line "
else
echo -n "$line "
fi
n=$[$n+1]
done
46 网卡和ip
题目要求
写一个getinterface.sh 脚本可以接受选项[i,I],完成下面任务:
1)使用格式:getinterface.sh [-i interface | -I ip]
2)当用户使用-i选项时,显示指定网卡的IP地址;当用户使用-I选项时,显示其指定ip所属的网卡。
例: sh getinterface.sh -i eth0 或者
sh getinterface.sh -I 192.168.0.1
3)当用户使用除[-i | -I]选项时,显示[-i interface | -I ip]此信息。
4)当用户指定信息不符合时,显示错误。(比如指定的eth0没有,而是eth1时)
参考答案:
#!/bin/bash
ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' > /tmp/ifs.txt
get_ip()
{
ip add show dev $1 |grep inet |awk '{print $2}' |awk -F '/' '{print $1}'
}
for eth in `cat /tmp/ifs.txt`
do
myip=`get_ip $eth`
if [ -z "$myip" ]
then
echo $eth
else
echo $eth $myip
fi
done > /tmp/if_ip.txt
if [ $# -ne 2 ] //判断用户输入的变量是不是2个
then
echo "请输入正确的格式: bash $0 -i 网卡 或者 bash $0 -I ip"
exit
fi
if [ $1 == "-i" ] //第一个参数是不是i
then
if awk '{print $1}' /tmp/if_ip.txt |grep -qw $2 //
then
eth=$2
ip1=`awk -v aeth=$eth '$1==aeth' /tmp/if_ip.txt|sed "s/$eth //"`
echo "网卡$2的ip是 $ip1"
else
echo "你指定的网卡不对,系统中的网卡有:`cat /tmp/ifs.txt|xargs`"
exit
fi
elif [ $1 == "-I" ]
then
if grep -qw " $2 " /tmp/if_ip.txt
then
eth=`grep -w " $2 " /tmp/if_ip.txt|awk '{print $1}'`
echo "IP $2对应的网卡是$eth"
else
echo "你指定的ip不对,系统中的IP有:`ip add |grep inet |awk '{print $2}'|awk -F '/' '{print $1}'|xargs`"
exit
fi
else
echo "请输入正确的格式: bash $0 -i 网卡 或者 bash $0 -I ip"
fi
47 随机3位数
题目要求
写一个脚本产生随机3位的数字,并且可以根据用户的输入参数来判断输出几组。 比如,脚本名字为 number3.sh。
执行方法:
1)bash number3.sh 会产生一组3位数字。
2)bash number3.sh 10 会产生10组3位数字。
#!/bin/bash
get_number()
{
for i in `seq 0 2`
do
a[$i]=$[$RANDOM%10]
done
echo ${a[@]}|sed s'/ //g'
}
if [ $# -eq 0 ]
then
get_number
elif [ $# -eq 1 ]
then
n=`echo $1|sed 's/[0-9]//g'`
if [ -n "$n" ]
then
echo "给定的参数必须是一个数字"
exit
fi
for i in `seq 1 $1`
do
get_number
done |xargs
else
echo "格式不对,正确的是格式是sh $0 [n],这里的n是一个数字。"
fi
48 是否安装包
题目要求
写一个shell,先判断是否安装httpd和mysql,没有安装进行安装,安装了检查是否启动服务,若没有启动则需要启动服务。
#!/bin/bash
if_install()
{
rpm -q $1 >/dev/null 2>/dev/null
if [ $? -eq 0 ]
then
echo "$1已经安装"
return 0
else
echo "$1没有安装"
return 1
fi
}
if_install httpd
if [ $? -eq 0 ]
then
if ! pgrep httpd >/dev/null
then
service httpd start
fi
else
yum install -y httpd
fi
if_install mysql-server
if [ $? -eq 0 ]
then
if ! pgrep mysqld start
then
service mysqld start
fi
else
yum install -y mysql-server
fi
题目要求
用shell脚本判断输入的日期是否合法。
比如20170110就是合法日期,20171332就不合法。
#!/bin/bash
if [ $# -ne 1 ] || [ ${#1} -ne 8 ]
then
echo "请输入正确的格式,sh $0 yyyymmdd"
exit 1
fi
y=`echo ${1:0:4}`
m=`echo ${1:4:2}`
d=`echo ${1:6:2}`
if echo $d|grep -q "^0"
then
d=`echo ${1:6:2}|sed 's/^0//'`
fi
if cal $m $y >/dev/null 2>/dev/null
then
if ! cal $m $y|grep -qw "$d"
then
echo "你给的日期是不合法的"
else
echo "日期合法"
fi
else
echo "你给的日期不合法"
fi
49 日期是否合法
题目要求
用shell脚本判断输入的日期是否合法。
比如20170110就是合法日期,20171332就不合法。
#!/bin/bash
if [ $# -ne 1 ] || [ ${#1} -ne 8 ]
then
echo "请输入正确的格式,sh $0 yyyymmdd"
exit 1
fi
y=`echo ${1:0:4}`
m=`echo ${1:4:2}`
d=`echo ${1:6:2}`
if echo $d|grep -q "^0"
then
d=`echo ${1:6:2}|sed 's/^0//'`
fi
if cal $m $y >/dev/null 2>/dev/null
then
if ! cal $m $y|grep -qw "$d"
then
echo "你给的日期是不合法的"
else
echo "日期合法"
fi
else
echo "你给的日期不合法"
fi
50 监控流量
题目要求
写一个监控网卡的脚本,需要满足以下要求:
每10分钟检测一次指定网卡的流量。
如果流量为0,则重启网卡。
#!/bin/bash
LANG=en
sar -n DEV 1 10|grep -w "$1" > /tmp/sar.tmp
in=`grep "Average:" /tmp/sar.tmp|awk '{print $5}'|sed 's/\.//'`
out=`grep "Average:" /tmp/sar.tmp|awk '{print $6}'|sed 's/\.//'`
if [ $in == "000"] && [ $out == "000" ]
then
ifdown $1
ifup $1
fi
51 判断网站是否正常
题目要求:
写一个shell脚本,通过curl -I 返回的状态码来判定所访问的网站是否正常。比如,当状态码为200时,才算正常。
#!/bin/bash
#这个脚本用来判定一个网站是否正常
#作者:倪实
#日期:2020-04-09
url="http://www.nsthink.com/index.php"
mail_user=123456@qq.com
code=`curl -I $url 2>/tmp/curl.err|head -l|awk '{print $2}'`
if [ -z "$code" ]
then
python mail.py $mail_user "$url访问异常" "`cat /tmp/curl.err`"
exit
elif [ $code !="200" ]
then
curl -I $url &> /tmp/curl.log
python mail.py $mail_user "$url访问异常 状态码$code" "`/tmp/curl.log`"
fi
52 打包小于5k的文件
题目要求
将用户家目录(考虑到执行脚本的用户可能是普通用户也可能是root)下面小于5KB的文件打包成tar.gz的压缩包,并以当前日期为文件名前缀,例如,2018-03-15.tar.gz。
#!/bin/bash
#这个脚本用来打包用户家目录下小于5k的文件
#作者
#日期:
t=`date +%F`
cd $HOME
tar czf $t.tar.gz `find ./ -type f -size -5k|xargs`
54 分析日志
题目要求
已知nginx访问的日志文件在/usr/local/nginx/logs/access.log内,请统计下早上10点到12点 来访ip最多的是哪个?
参考日志
111.199.186.68 – [15/Sep/2017:09:58:37 +0800] “//plugin.php?id=security:job” 200 “POST //plugin.php?id=security:job HTTP/1.1″”http://a.lishiming.net/forum.php?mod=viewthread&tid=11338&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36”
203.208.60.208 – [15/Sep/2017:09:58:46 +0800] “/misc.php?mod=patch&action=ipnotice&_r=0.05560809863330207&inajax=1&ajaxtarget=ip_notice” 200 “GET /misc.php?mod=patch&action=ipnotice&_r=0.05560809863330207&inajax=1&ajaxtarget=ip_notice HTTP/1.1″”http://a.lishiming.net/forum.php?mod=forumdisplay&fid=65&filter=author&orderby=dateline” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36”
#!/bin/bash
#这个脚本用来分析nginx访问日志
export LANG=en
log="/usr/local/nginx/logs/access.log"
t=`date +%d/%b%Y:[01]:[0-5]:[0-9]:`
egrep "$t" $log|awk '{print $1}' |sort -n |uniq -c|sort -n|tail -1|awk '{print $2}'
55 打印数字
题目要求
写一个shell脚本。提示输入一个暂停的数字,然后从1打印到该数字。然后询问是否继续。继续的话再输入一个数字接着打印,否则退出脚本。
例:如果输入的是5,打印1 2 3 4 5,然后继续输入15,然后打印6 7 …14 15 以此类推。
参考答案
#!/bin/bash
#这个脚本用来打印数字
read -p "Please input a number: " n
n1=`echo $n |sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "Please input a number."
exit
fi
for i in `seq 1 $n`
do
echo $i
done
read -p "If continue? y/n" c
case $c in
n|N)
exit
;;
y|Y)
read -p "Please input a number: " n2
n3=`echo $n2|sed 's/[0-9]//g'`
if [ -n "$n3" ]
then
echo "Please input a number."
exit
fi
if [ $n2 -le $n ]
then
echo "$n2 should grater than $n."
exit
fi
for i in `seq $[$n+1] $n2`
do
echo $i
done
;;
*)
echo "Please input y or n."
;;
esac
56 监控22端口是否被封
题目要求
一个同学不小心用iptables规则把sshd端口22给封掉了,结果不能远程登陆,要想解决这问题,还要去机房,登录真机去删除这规则。 问题来了,要写个监控脚本,监控iptables规则是否封掉了22端口,如果封掉了,给打开。 写好脚本,放到任务计划里,每分钟执行一次。
#!/bin/bash
iptables -nvL INPUT --line-numbers|grep -w 'dpt:22'|awk '$4 ~/REJECT|DROP/ {print $1}'
n=`wc -l /tmp/iptables.log`
if [ $n -gt 0 ]
then
for n in `tac /tmp/iptables.log`
do
iptables -D INPUT $n
done
fi
1 * * * * bash /iptables_22.sh
57 给文件增加内容
题目要求
在文本文档1.txt第5行(假设文件行数大于5)后面增加如下内容:
# This is a test file.
# Test insert line into this file.
#!/bin/bash
#这个脚本用来给文件增加行
n=0
cat 1.txt |while read line
do
n=$[$n+1]
if [ $n -eq 5 ]
then
echo $line
echo -e "# This is a test file.\n# Test insert line into this file."
else
echo $line
fi
done
58 备份etc目录
题目要求
设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式"yymmdd_etc.tar.gz",yy为年,mm为月,dd为日。
#!/bin/bash
d1=`date +%d`
d2=`date +%y%m%d`
if [ $d1 == "01" ]
then
cd /etc
tar -czf /root/bak/$d2_etc.tar.gz ./
fi
58 列出重复次数最多的10个单词
题目要求
将文件内所有的单词的重复次数计算出来,只需要列出重复次数最多的10个单词。
#!/bin/bash
#这个脚本用来找出重复的单词
for w in `sed 's/[^a-zA-Z]/ /g' $1`
do
echo $w
done |sort |uniq -c|sort -nr|head
59 平均随机分组
题目要求
需求是,把所有的成员平均分成若干个小组。这里,提供一个人员列表,比如成员有50人,需要分成7个小组,要求随机性,每次和每次分组的结果应该不一致。
参考人员名单
xiaoguisheng
guoyuqing
xiongyongzheng
mengjintang
chaizuzhou
zhousheng
xufangming
zhaoliangyun
hanshiru
wangxianyi
zhangjipei
luxiuli
yangshugen
guoyongzhi
lijianguo
wuqiongchen
dinglin
yaoyashan
yinzijia
wangbencheng
liuxiuwen
chenzuqi
leyuguo
baozongyao
fenghao
sunxiaoquan
zhangyaxian
lijiuzhe
dulichun
lixi
shenpeiwen
zousilin
luoping
chaiyan
fandaozhang
huzixiang
jinzhen
zhujunfeng
liqianbiao
hangyanliang
luorenjian
loujianji
fujianzhou
gengyiwu
jinjigui
liuzhizhong
lisanyan
lisili
zhangyiyu
songguozhen
zhangxinghua
zhaozhiyong
huanghe
xiaojie
fanhongfei
wangguiwen
renshumin
songfuying
zhanghaibo
liguangqun
puaihua
yanzhihua
gaojixian
liulai
funing
chenruizhi
chendaxin
laishaoying
xujian
xiaozhekou
xuxiaping
jiangchunqing
#!/bin/bash
#这个脚本用来给人员分组
#人员列表文件
f=member.txt
#小组数
group_n=7
#人员总数
member_n=`wc -l $f|awk '{print $1}'`
#根据姓名计算该用户所在小组的id
get_n()
{
#根据姓名计算cksum值
l=`echo $1|cksum|awk '{print $1}'`
#获取一个随机数
n1=$RANDOM
#cksum值和随机数相加,然后除以小组数取余,这样可以确保每次获取到的余数都不一样
n2=$[$n1+$l]
g_id=$[$n2%$group_n]
#假如小组数为7,则余数范围0-6,如果余数为0,则小组为7
if [ $g_id -eq 0 ]
then
g_id=$group_n
fi
echo $g_id
}
for i in `seq 1 $group_n`
do
#n_$i.txt为临时文件,用来记录该小组内的成员
#脚本之前执行过,则该文件会存在,本次执行脚本前应该删除掉这个临时文件
[ -f n_$i.txt ] && rm -f n_$i.txt
done
shuf $f|while read name
do
#计算用户所在小组的id
g=`get_n $name`
#将人员追加写入到他对应的小组里
echo $name >> n_$g.txt
done
#定义计算文件行数的函数
nu(){
wc -l $1|awk '{print $1}'
}
#获取组员人数最多的小组
max(){
ma=0
for i in `seq 1 $group_n|shuf`
do
n=`nu n_$i.txt`
if [ $n -gt $ma ]
then
ma=$n
fi
done
echo $ma
}
#获取组员人数最少的小组
min(){
mi=$member_n
for i in `seq 1 $group_n|shuf`
do
n=`nu n_$i.txt`
if [ $n -lt $mi ]
then
mi=$n
fi
done
echo $mi
}
#定义四舍五入函数
div()
{
n=`echo "scale=1;$1/$2"|bc`
n1=`echo "scale=1;$n+0.5"|bc`
echo $n1|cut -d. -f1
}
#小组组员平均值(非四舍五入)
ava_n=$[$member_n/$group_n]
#小组组员平均值(四舍五入)
ava_n1=`div $member_n $group_n`
if [ $ava_n -eq $ava_n1 ]
then
#定义初始最小值
ini_min=1
#以下while循环要做的事情,就是要把人数多的组里的人搞到人数少的组里去
#此while循环的条件是,当人数最少的组成员数小于组员平均值
while [ $ini_min -lt $ava_n1 ]
do
#找出人数最多的组
m1=`max`
#找出人数最少的组
m2=`min`
for i in `seq 1 $group_n|shuf`
do
n=`nu n_$i.txt`
#找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个即可)
if [ $n -eq $m1 ]
then
f1=n_$i.txt
#找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个即可)
elif [ $n -eq $m2 ]
then
f2=n_$i.txt
fi
done
#取f1中最后一个人名
name=`tail -n1 $f1`
#将这个人名追加写入f2中
echo $name >> $f2
#在f1中删除刚刚取走的人名
sed -i "/$name/d" $f1
#把此时的最少组人员数赋值给ini_min
ini_min=`min`
done
else
#定义初始最大值
ini_max=$member_n
while [ $ini_max -gt $ava_n1 ]
do
#找出人数最多的组
m1=`max`
#找出人数最少的组
m2=`min`
for i in `seq 1 $group_n|shuf`
do
n=`nu n_$i.txt`
#找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个即可)
if [ $n -eq $m1 ]
then
f1=n_$i.txt
#找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个即可)
elif [ $n -eq $m2 ]
then
f2=n_$i.txt
fi
done
#取f1中最后一个人名
name=`tail -n1 $f1`
#将这个人名追加写入f2中
echo $name >> $f2
#在f1中删除刚刚取走的人名
sed -i "/$name/d" $f1
#把此时的最少组人员数赋值给ini_min
ini_max=`max`
done
fi
for i in `seq 1 $group_n`
do
echo -e "\033[34m$i 组成员有:\033[0m"
cat n_$i.txt
#把临时文件删除
rm -f n_$i.txt
echo
done
}
60 比较数字大小
需求:
写一个shell脚本,比较两个数的大小,支持浮点数,两个数通过shell参数的形式提供。
#!/bin/bash
#这两个脚本用来比较两个数大小
if [ $# -ne 2 ]
then
echo "请提供两个参数"
exit
fi
if_number()
{
if echo $1|grep -q '^-'
then
nu=`echo $1|sed 's/^-//'`
else
nu=$1
fi
n=`echo $nu|sed 's/[0-9.]//g'`
if [ -n "$n" ]
then
echo "$1不是合法数字"
exit
fi
}
if_number $1
if_number $2
n1=`echo "$1>$2"|bc`
if [ $n1 -eq 1 ]
then
echo "$1 > $2"
else
if [ "$1" == "$2" ]
then
echo "$1 = $2"
else
echo "$1 < $2"
fi
fi
61 找出a,b文件差异行
题目要求
有两个文件a.txt和b.txt,需求是,把a.txt中有的但b.txt中没有的行找出来,并写入到c.txt,然后计算c.txt文件的行数。
#!/bin/bash
cat a.txt|while read line
do
if ! grep -q "$line" b.txt
then
echo $line
fi
done >c.txt
wc -l c.txt
62 找出a,b文件差异行
题目要求
把当前用户下所有进程名字中含有"java"的进程关闭。
#!/bin/bash
#这个脚本用来杀进程
ps -u $USER|awk '$NF ~/java/ {print $1}' |xargs kill
63 并发备份mysql表
题目要求
用shell实现,以并发进程的形式将mysql数据库所有的表备份到当前目录,并把所有的表压缩到一个压缩包文件里。
假设数据库名字为mydb,用户名为aming,密码为passwd。
#!/bin/bash
#这个脚本用来并发备份数据库
N=5
mysql -uaming -ppasswd mydb -e "show tables"|sed '1d' > /tmp/table.txt
n=`wc -l /tmp/table.txt|awk '{print $1}'
div()
{
n=`echo "scale=1;$1/$2"|bc`
n1=`echo "scale=1;$n+0.5"|bc`
echo $n1|cut -d. -f1
}
n1=`div $n $N`
split -l $n1 /tmp/table.txt
myd()
{
for t in `cat $1`
do
mysqldump -uaming -ppasswd mydb $t > $t.sql
done
}
for f in xaa xab xac xad xae
do
myd $f &
done
wait
tar czf mydb.tar.gz *.sql
rm -f *.sql
64 并发备份mysql表
题目要求
一个网站,使用了cdn,全国各地有几十个节点。需要你写一个shell脚本来监控各个节点是否正常。 假如
1,监控的url为www.nsthink.com/index.php
2,源站ip为88.88.88.88。
#!/bin/bash
#这个脚本用来监控CDN节点
s_ip=88.88.88.88
url=www.aminglinux.com/index.php
ipf=/data/ip.list
curl -x$s_ip:80 $url1 2>/dev/null >/tmp/$ip.txt
for ip in `cat $ipf`
do
curl -x$ip:80 $url 2>/dev/null >/tmp/$ip.txt
diff /tmp/source.txt /tmp/$ip.txt > /tmp/$ip.diff
n=`wc -l /tmp/$ip.diff|awk '{print $1}'`
if [ $n -gt 0 ]
then
echo "节点$ip有异常."
fi
done
65 破解字符串
题目要求
已知下面的字符串是通过RANDOM随机数变量md5sum|cut -c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字? 21029299 00205d1c a3da1677 1f6d12dd 890684ba
参考答案:
#!/bin/bash
#这个脚本用来破解字符串
for i in `seq 0 32767`
do
m=`echo $i|md5sum|cut -c 1-8 `
echo $i $m
done >/tmp/md5.txt
cat > c.txt <
66 判断CPU厂商
题目要求
写一个脚本:
判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。
如果其生产商为AuthenticAMD,就显示其为AMD公司;
如果其生产商为GenuineIntel,就显示其为Intel公司;
否则,就说其为非主流公司。
#!/bin/bash
#这个脚本用来判断CPU厂商
cpu=`grep '^vender_id' /proc/cpuinfo |head -1|awk -F ': ' '{print $2}'`
#if [ $cpu == "AuthenticAMD" ]
#then
# echo "CPU厂商是Intel."
#else
# echo "CPU厂商是非主流厂商。"
#fi
case $cpu in
AuthenticAMD)
echo "CPU厂商是AMD."
;;
GenuineIntel)
echo "CPU厂商是Intel."
;;
*)
echo "CPU厂商是非主流厂商."
;;
esac
67 监控CPU使用率
题目要求
用shell写一个监控服务器cpu使用率的监控脚本。
参考答案:
#!/bin/bash
#用来计算CPU使用率
mail_user=906288036@qq.com
m_mail() {
log=$1
t_s=`date +%s`
t_s2=`date -d "1 hours ago" +%s`
if [ ! -f /tmp/$log ]
then
#创建$log文件
touch /tmp/$log
#增加a权限,只允许追加内容,不允许更改或删除
chattr +a /tmp/$log
#第一次告警,可直接写入1小时以前的时间戳
echo $t_s2 >> /tmp/$log
fi
#无论$log文件是否是刚刚创建,都需要查看最后一行的时间戳
t_s2=`tail -l /tmp/$log|awk '{print $1}'`
#取出最后一行即上次告警的时间戳后,理机写入当前的时间戳
echo $t_s>>/tmp/$log
#取两次时间戳差值
}
68 打印子进程
题目要求:
给出一个进程PID,打印出该进程下面的子进程以及子进程下面的所有子进程(只需要考虑子进程的子进程,再往深层次则不考虑)
核心要点:
ps -elf结果中PPID那一列为父进程PID, pstree -p 2 命令也可以查看,软件包psmisc,此处我们用ps -elf 编辑脚本
[root@docker:~]# cat printid.sh
#/bin/bash
#这个脚本用来打印子进程
ps -elf > /tmp/pid.txt
read -p "Please input a pid: " p
if [ -z "$p" ]
then
echo "你没有输入任何pid,请输入一个pid:"
exit
fi
if ! grep -qw "$p" /tmp/pid.txt
then
echo "你输入的pid不存在"
exit
fi
get_children_pid()
{
p1=$1
ps -elf |awk -v p2=$p1 '$5==p2 {print $4}' > /tmp/$p1.txt
n=`wc -l /tmp/$p1.txt|awk '{print $1}'`
if [ $n -eq 0 ]
then
echo "进程$1下没有子进程"
else
echo "进程$1下的子进程是:"
cat /tmp/$p1.txt
fi
}
get_children_pid $p
#下面代码获取子进程的子进程
for c_p in `cat /tmp/$p.txt`
do
get_children_pid $c_p
done
69 lamp增加项目
需求背景:
服务器上,跑的lamp环境,上面有很多客户的项目,每个项目就是一个网站,由于客户在不断增加,每次增加客户,就需要配置相应mysql,ftp,以及httpd,这种工作具有很强的重复性,所以用脚本实现非常合适。mysql增加的是对应客户项目的数据库,用户密码,ftp增加的是对应项目的用户,密码(使用vsftpd,虚拟用户模式),httpd就是要增加虚拟主机配置段。
核心要点:
清楚增加mysql库和用户,增加httpd虚拟主机,增加ftp用户的命令,只要能在命令行搞定,那么在脚本中就没问题。
#!/bin/bash
#本脚本功能是在LAMP环境中增加站点,包括apache配置,ftp增加用户,mysql增加库和用户
#网站目录
webdir=/data/wwwroot
#ftp的虚拟用户配置文件目录
ftpuserfile=/root/login
#mysql命令行登陆root
mysqlc="/usr/local/mysql/bin/mysql -uroot -p123456"
#apache虚拟主机配置文件
httpd_config_f="/usr/local/apache2/conf/extra/httpd-vhosts.conf"
#定义增加mysql库和用户的函数
add_mysql_user()
{
#生成随机密码
mysql_p=`mkpasswd -s 0 -1 12`
#将密码保存到临时文件里,这里的$pro为用户自定义的项目名字
echo "$pro $mysql_p" >/tmp/$pro.txt
#这里使用嵌入文档的形式(需顶格),将创建用户并授权的命令传递给mysql
$mysqlc <> $ftpuserfile
echo "$ftp_p" >> $ftpuserfile
#将用户、密码文件转换为密码db文件
db_load -T -t hash -f $ftpuserfile /etc/vsftpd/vsftpd_login.db
cd $ftpudir
#这里的aaa是一个文件,是一个测试项目,可以作为配置模板
cp aaa $pro
#把里面的aaa改为新的项目名字
sed -i "s/aaa/$pro/" $pro
#重启vsftpd服务
/etc/init.d/vsftpd restart
}
#定义增加apache虚拟主机的函数
config_httpd()
{
#增加网站根目录,和域名保持一致,这里的$dom为用户自定义的域名
mkdir $webdir/$dom
#将网站根目录属主属组设置为ftp用户
chown vsftpd:vsftpd $webdir/$dom
#用嵌入文档(需顶格),把虚拟主机配置写入到配置文件里
cat >> $httpd_config_f <
DocumentRoot $webdir/$dom
ServerName $dom
AllowOverride none
Require all granted
EOF
#重载apache服务
/usr/local/apache2/bin/apachectl graceful
}
read -p "input the project name: " pro
read -p "input the domain: " dom
add_mysql_user
add_ftp_user
config_httpd
71 判断文件存在并计算单词个数
题目要求:
判断所给目录内哪些二级目录下有没有text.txt文件。
有text.txt文件的二级目录,计算出该test.txt文件里面所给出单词的次数。
假如脚本名字为1.sh, 运行脚本的格式为 ./1.sh 123 root,其中123为目录名字,而root为要计算数量的单词。
参考答案
#!/bin/bash
#这个脚本用来判断文件是否存在并计算单词个数
if [ $# -ne 2 ]
then
echo "请提供两个参数,第一个参数是目录名字,第二个参数是单词"
exit
fi
cd $1
for f in `ls .`
do
if [ -d $f ]
then
if [ -f $f/test.txt ]
then
n=`grep -cw "$2" $f/test.txt`
echo "$1/$f目录下面有test.txt, 该test.txt里面的有$n个$2."
fi
fi
done
71 简易计算器
题目要求:
用shell写一个简易计算器,可以实现加、减、乘、除运算,假如脚本名字为1.sh,执行示例:./1.sh 1 + 2
核心要点:
case in esac结构
#!/bin/bash
#这个脚本用来实现简易计算器
if [ $# -ne 3 ]
then
echo "你给的参数个数不对,应该3个参数"
exit
fi
if_number()
{
n1=`echo $1|sed 's/[0-9.]//g'`
if [ -n "$n1" ]
then
echo "$1不是数字."
exit
fi
}
if_number $1
if_number $3
case $2 in
+)
echo "$1+$3"|bc
;;
-)
echo "$1-$3"|bc
;;
\*)
echo "$1*$3"|bc
;;
/)
echo "scale=2;$1/$3"|bc
;;
*)
echo "你给出的格式不对,第二个参数只能是+,-,*,/"
;;
esac
72 打印正方形
题目要求:
交互式脚本,根据提示,需要用户输入一个数字作为参数,最终打印出一个正方形。在这里我提供一个linux下面的特殊字符■,可以直接打印出来。
示例: 如果用户输入数字为5,则最终显示的效果为
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
参考答案:
#!/bin/bash
#这个脚本用来打印正方形
while :
do
read -p "Please input a nuber: " n
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "$n is not a nuber."
continue
else
break
fi
done
#以上判断输入的是否是纯数字,不是纯数字循环输入直到输入的为纯数字,如果输入的是纯数字,则退出
for i in `seq 1 $n`
do
for j in `seq 1 $n`
do
echo -n "■ " //-n不换行输出
done
echo
done
#以上为一个循环里面嵌套一个循环,打印$n行$n列
73 问候用户
题目要求:
写一个脚本,依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么,如:
Hello, root,your UID is 0.
[root@aliyun:~/server/scripts/shell100]# cat 74.sh
#!/bin/bash
#这个脚本用来问候用户
cat /etc/passwd |while read line
do
username=`echo $line|awk -F ':' '{print $1}'`
uid=`echo $line|awk -F ':' '{print $3}'`
echo "hello,$username,your uid is $uid"
done
74 格式化输出xml
题目要求
linux系统 /home目录下有一个文件test.xml,内容如下:
zzz
aaa
xxx
yyy
请写出shell脚本删除文件中的注释部分内容,获取文件中所有artifactItem的内容,并用如下格式逐行输出: artifactItem:groupId:artifactId:aaa
#!/bin/bash
#这个脚本用来格式化xml文件
sed '//d' test.xml > test2.xml
egrep -n '