41、题目要求 : 问候脚本
编写一个问候程序,它执行时能根据系统当前的时间向用户输出问候信息。假设从半夜到中午为早晨,中午到下午六点为下午,下午六点到半夜为晚上。
参考答案
#!/bin/bashd=`date +%H`if [ $d -ge 0 -a $d -lt 7 ]then tag=1elif [ $d -ge 7 -a $d -lt 12 ]then tag=2elif [ $d -ge 12 -a $d -lt 18 ]then tag=3else tag=4ficase $tag in 1) echo "早晨好" ;; 2) echo "上午好" ;; 3) echo "下午好" ;; 4) echo "晚上好" ;; *) echo "脚本出错啦" ;;esac
实例 :
执行脚本,查看运行结果,脚本没有问题。date命令查看系统当前的时间
注意 :
[ $d -ge 0 -a $d -lt 7 ] #大于等于0,小于7
[ $d -ge 7 -a $d -lt 12 ] #大于等于7,小于12
[ $d -ge 12 -a $d -lt 18 ] #大于等于12,小于18
d=`date -d -10 hours +%H` #时间后退10个小时,就变成了脚本执行的结果早上好
42、题目要求 : 菜单脚本
写一个shell脚本,实现简单的弹出式菜单功能,用户能根据显示的菜单项从键盘选择执行对应的命令。
参考答案
#!/bin/bashPS3="Please input your choice(1-4): "select i in w ls pwd quitdo case $i in w) w ;; ls) ls ;; pwd) pwd ;; quit) exit ;; *) echo "Please input 1-3." ;; esacdone
参考答案2
#!/bin/bashecho -e "1) w\n2) ls\n3) pwd\n4) quit"while :doread -p "Please input your choice(1-4): " ccase $c in 1) w ;; 2) ls ;; 3) pwd ;; 4) exit ;; *) echo "Please input 1-4." ;;esacdone
实例 :
执行脚本,输入数字,执行对应的命令。
注意 :
w\n2) ls\n3) pwd\n4) #使用 数字去代替命令w,ls,pwd
43、题目要求 : 检查用户是否登录
写一个shell脚本,执行中每隔5分钟检查指定的用户是否登录系统,用户名从命令行输入,如果指定的用户已经登录,则显示相关信息。
参考答案
#!/bin/bashwhile :do if w|sed '1'd|awk '{print $1}'|grep -qw "$1" then echo "用户$1 已经登录系统." exit fi sleep 300done
实例 :
查看当前的用户
执行脚本,输入用户名,查看该用户有没有登录。
注意 :
if w|sed '1'd|awk '{print $1}'|grep -qw "$1" #查找并去掉出显示出来的第一行,
44、题目要求 : 检查系统是否入侵
先普及一个小常识,我们用ps aux可以查看到进程的PID,而每个PID都会在/proc内产生。如果查看到的pid在proc内是没有的,则进程被人修改了,这就代表系统很有可能已经被入侵过了。 请用上面知识编写一个shell,定期检查下自己的系统是否被人入侵过
参考答案
#!/bin/bashpp=$$ps -elf |sed '1'd > /tmp/pid.txtfor pid in `awk -v ppn=$pp '$5!=ppn {print $4}' /tmp/pid.txt`do if ! [ -d /proc/$pid ] then echo "系统中并没有pid为$pid的目录,需要检查。" fi done
实例 :
使用命令ls -l /proc,查看文件的pid,然后通过pid,查看进程。
打印出,含有pid的行
打印出只含有pid的行
注意 :
脚本要把ps、sed、awk中的PID过滤掉,只剩下进程的pid。
ps -elf |sed '1'd > /tmp/pid.txt #列出pid,并删除第一行,将结果写入/tmp/pid.txt
for pid in `awk -v ppn=$pp '$5!=ppn {print $4}' /tmp/pid.txt` #awk显示出来的pid在第四列,把第四列过滤掉;把ps -elf显示出来的第四列,打印出来。-v : 引用的意思,$5!=ppn {print $4} : $5不等于ppn $4
45、题目要求 : 三行并一行
想办法把文本里面每三行内容合并到一行 例如:1.txt内容
1234567
处理后应该是
1 2 34 5 67
【核心要点】
while read 逐行遍历
echo -n 不换行
参考答案
#!/bin/bashn=1cat $1 |while read line do n1=$[$n%3] if [ $n1 -eq 0 ] then echo "$line" else echo -n "$line " fi n=$[$n+1]done
实例 :
脚本执行结果
注意 :
n1=$[$n%3] #$n能够被3整除
$n1 -eq 0 #-eq等于 0,换行。
46、题目要求 : 网卡和ip(1)、网卡和ip(2)
写一个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时)
【核心要点】
两个参数$1只能是-i或者-I , $2只能是网卡名字或者IP地址
把网卡名字和IP地址写到一个临时文件里备用
参考答案
#!/bin/baship add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' > /tmp/ifs.txtget_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 fidone > /tmp/if_ip.txt if [ $# -ne 2 ]then echo "请输入正确的格式: bash $0 -i 网卡 或者 bash $0 -I ip" exitfiif [ $1 == "-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 fielif [ $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 fielse echo "请输入正确的格式: bash $0 -i 网卡 或者 bash $0 -I ip"fi
实例 :
查看系统中有哪些网卡
查看lo网卡第二行
注意 :
ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' > /tmp/ifs.txt #将网卡和网卡IP对应的关系,写入到 /tmp/ifs.txt 文件中
ip add show dev $1 |grep inet |awk '{print $2}' |awk -F '/' '{print $1}' #只显示网卡的IP地址。
if awk '{print $1}' /tmp/if_ip.txt |grep -qw $2 #
if [ -z "$myip" ] #如果这个变量为空,
47、题目要求 : 随机3位数
写一个脚本产生随机3位的数字,并且可以根据用户的输入参数来判断输出几组。 比如,脚本名字为 number3.sh。
执行方法:
1)bash number3.sh 会产生一组3位数字。
2)bash number3.sh 10 会产生10组3位数字。
参考答案
#!/bin/bashget_number(){ for i in `seq 0 2` do a[$i]=$[$RANDOM%10] done echo ${a[@]}|sed s'/ //g'}if [ $# -eq 0 ]then get_numberelif [ $# -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
实例 :
脚本运行结果
注意 :
if [ -n "$n" ] #如果-n不为空,说明“给定的参数必须是一个数字”
elif [ $# -eq 1 ] #eq 等于1
48、题目要求 : 是否安装包
写一个shell,先判断是否安装httpd和mysql,没有安装进行安装,安装了检查是否启动服务,若没有启动则需要启动服务。
说明 :操作系统为cnetos6,httpd和mysql全部为rpm包安装
【核心要点】
rpm -q 包名 判断是否安装
service xxx start #启动
参考答案
#!/bin/bashif_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 httpdif [ $? -eq 0 ]then if ! pgrep httpd >/dev/null then service httpd start fielse yum install -y httpdfiif_install mysql-serverif [ $? -eq 0 ]then if ! pgrep mysqld >/dev/null then service mysqld start fielse yum install -y mysql-serverfi
实例 :
查看软件是否安装
脚本执行的过程
注意 :
rpm -q $1 >/dev/null 2>/dev/null #判断是否安装,如果安装写入/dev/null,未安装;$1就是包名
49、题目要求 : 日期是否合法
用shell脚本判断输入的日期是否合法。
比如20170110就是合法日期,20171332就不合法。
参考答案
#!/bin/bashif [ $# -ne 1 ] || [ ${#1} -ne 8 ]then echo "请输入正确的格式,sh $0 yyyymmdd" exit 1fiy=`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//'`fiif cal $m $y >/dev/null 2>/dev/nullthen if ! cal $m $y|grep -qw "$d" then echo "你给的日期是不合法的" else echo "日期合法" fielse echo "你给的日期不合法"fi
实例 :
查看系统时间,月和年。
修改系统时间为指定的时间
取前三个,取前四个
脚本执行的结果
注意 :
if [ $# -ne 1 ] || [ ${#1} -ne 8 ] # $#不等于1 或者 ${#1} 不等于8,提示 : “请输入正确的格式,sh $0 yyyymmdd”
if echo $d|grep -q "^0" #查找不以0开头的
if ! cal $m $y|grep -qw "$d" #
if cal $m $y >/dev/null 2>/dev/null #日历月和年,正确和错误都输入到/dev/null
50、题目要求 : 监控流量
写一个监控网卡的脚本,需要满足以下要求:
-
每10分钟检测一次指定网卡的流量。
-
如果流量为0,则重启网卡。
【核心要点】
sar -n DEV # 查看dev网卡的流量
ifdown xxx; ifup xxx #下载的速度,和上传的速度
参考答案
#!/bin/bashLANG=ensar -n DEV 1 10|grep -w "$1" > /tmp/sar.tmpin=`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 $1fi
实例 :
10秒一次网卡流量监测
查看lo网卡的流量,10秒一次网卡流量监测,average为0时,需要重启网卡。
脚本执行的结果
注意 :
sar -n DEV 1 10|grep -w "$1" > /tmp/sar.tmp #把网卡流量的每10秒统计一次的结果的第一行,写入到 /tmp/sar.tmp
in=`grep "Average:" /tmp/sar.tmp|awk '{print $5}'|sed 's/\.//'` #进入的流量的第五行,输入到/tmp/sar.tmp,去掉前面的小数点。
out=`grep "Average:" /tmp/sar.tmp|awk '{print $6}'|sed 's/\.//'` #输出的流量的第六行,输入到/tmp/sar.tmp,去掉前面的小数点。
if [ $in == "000" ] && [ $out == "000" ] #当进入的和输出的,都为0时,重启网卡。
来源 :https://github.com/aminglinux/shell100/blob/master/13.md