编者注:shell脚本的学习只有一个方法,那就是多练,多练,多练。嗯,重要的事情说三遍。
-
-
-
- RANDOM和Seq的使用
- awk练习
- sed 练习
- shell考试题
- system tools菜单 main
- 搭建本地yum源
- 当前eth接口的有效ip和有效网关
- 点歌程序脚本
- 给登录到当前主机的所有非root用户终端发送一句话
- 函数 菜单 main
- 监控脚本的菜单和main函数的实现
- 监控脚本
- 监控内存的使用情况
- 监听mysql服务是否开启
- netstat命令-anplut
- 截取本机上所有网卡的ip地址和子网网关
- 判断IP是否合法
- 怎么得到密码的长度
- for循环批量添加
- 用while循环批量添加20个用户
- 使用条件测试
- 双色球的选择数组和seq的应用
- 统计某个文件夹下有多少个文件夹
- 统计某文件夹下某种文件后缀名的文件的数目
- 统计日志里访问次数最多的10个ip地址
- dd
- 选择菜单的应用
- 芝麻开门 字符串比较
- 最经典的ping检查能用
-
-
RANDOM和Seq的使用
练习1:编写脚本清空所有arp缓存记录:
#!/bin/bash
for i in $(arp | tail -n +2|tr -s ' ' |cut -d' ' -f1)
do
arp -d $i
done
练习2:产生3个随机数:
方法1:
#for i in {0..9};do echo $RANDOM;done
方法2:
#for i in $(seq 10);do echo $RANDOM;done
练习3:倒数五秒:
#!/bin/bash
for i in $(seq 5 -1 1)
do
echo -en "$i\n";
sleep 1
done
echo -e "\e[31m开始!\e[0m"
练习4:批量添加用户:
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST --》从列表文件读取文件名
do
useradd $UNAME
echo "123456" | passwd --stdin $UNAME --》通过管道指定密码字串
done
awk练习
例子:
# cat passwd|awk -F: 'BEGIN{print "############"}$3<100{print $1,$3,$6}END{print "@@@@@@@@@@@@@@"}'
结果:
############
root 0 /root
dbus 81 /
rpc 32 /var/cache/rpcbind
rpcuser 29 /var/lib/nfs
haldaemon 68 /
postfix 89 /var/spool/postfix
mysql 27 /var/lib/mysql
@@@@@@@@@@@@@@
例1:只有模式时,相当于grep
# cat passwd|awk '/liu/'
liu1:x:508:508::/home/liu1:/bin/bash
liu2:x:509:509::/home/liu2:/bin/bash
例2:只有动作时,就直接执行动作。
# who|awk '{print $2}'
tty1
pts/0
# who
root tty1 2016-06-24 23:20
root pts/0 2016-06-24 23:21 (liupeng.lan)
例3:输出以h开头的行的第一列和第七列。
# cat passwd|awk -F: '/^h/{print $1,$7}'
haldaemon /sbin/nologin
例4:显示不是以h开头的行的第一列和第七列
awk -F: '/^[^h]/{print $1,$7}' /etc/passwd
例5:以:或者/作为分隔符显示第1列和第10列
awk -F'[:/]' '{print $1,$10}' /etc/passwd
例6:以【空格:/】作为分隔符–》非常方便!!!
例1:在$2里查找匹配/pts/的,有就输出$1。
#who | awk '$2 ~ /pts/{print $1}‘
例2:输出uid为两位的用户名和uid。
# cat passwd|awk -F: '$3 ~/\<..\>/{print $1,$3}'
结果:
dbus 81
rpc 32
rpcuser 29
haldaemon 68
postfix 89
mysql 27
例3:输出1~100能被5整除的或者以1开头的数字。
#seq 100 | awk '$1 % 5 == 0 || $1 ~ /^1/{print $1}'
例4:显示uid大于等于500并且家目录在/home下同时shell为bash结尾的用户名,uid,家目录,shell。
# cat passwd|awk -F: '$3>=500&&$6 ~/^\/home/&&$7 ~/bash/{print $1,$3,$6,$7}'
aaa 500 /home/aaa /bin/bash
stua6 501 /home/stua6 /bin/bash
stuv1 502 /home/stuv1 /bin/bash
stuv2 503 /home/stuv2 /bin/bash
练习1:查找出用户名里包含liu的用户,输出用户名和uid及shell。
# cat passwd|awk -F':' '$1 ~/liu/{print $1,$3,$6}'
liu1 508 /home/liu1
liu2 509 /home/liu2
liu3 510 /home/liu3
liu4 511 /home/liu4
liu5 512 /home/liu5
liu 539 /home/liu
练习2:查找出/etc/passwd文件里用户名包含liu并且使用bash的用户。
# cat passwd|awk -F':' '$1 ~/liu/&&$7 ~/bash/{print $1,$7}'
liu1 /bin/bash
liu2 /bin/bash
liu3 /bin/bash
liu4 /bin/bash
liu5 /bin/bash
liu /bin/bash
例题:
# awk 'BEGIN{print "line one\nline two\nline three"}'
line one
line two
line three
# awk 'END{print "line one\nline two\nline three"}'line one
按Ctrl+D才显示最后三行。
line one
line two
line three
例:显示文件的行数.
# cat -n passwd|awk 'BEGIN{i=0}{i++}END{print i}'
分析:每取一行,i++。最后i的值就正好是passwd文件的行数。
例1:显示每行的字段数目
#awk '{print NF}' /etc/passwd(默认分隔符是空白,所以字段数大都是1咯)
# awk -F: '{print NF}' /etc/passwd(指定了分隔符了,就是7咯)
例2:显示每行的第一字段和最后一个字段
#awk -F: '{print $1,$NF}' /etc/passwd
例3:显示每行的行号和内容
#awk -F: '{print NR,$0}' /etc/passwd
例4:显示第一列和第七列,中间用—隔开
#awk -F: 'BEGIN{OFS="---"}{print $1,$7}' /etc/passwd
简单写法:
#awk -F: 'OFS="---"{print $1,$7}'/etc/passwd
例5:显示符合模式的用户名和所在的行号最后显示总行号
#awk 'BEGIN{FS=":"}/bash$/{print NR,$1}END{print NR}' /etc/passwd
例6:显示文件的3到5行(带行号,带内容)
#awk‘NR==3,NR==5{print NR,$0}’ /etc/passwd
显示4或7行(带行号,带内容)
#awk 'NR==4||NR==7{print NR,$0}' /etc/passwd
例7:显示文件的前10行(带行号,带内容)
#awk 'NR<=10{print NR,$0}' /etc/passwd
例8:显示文件的前10行和30到40行
# awk 'NR<=10||NR>30&&NR<=40{print NR,$0}' /etc/passwd
练习:
1.分析下面三条命令的区别,为什么
①#awk ‘BEGIN{print NR}’ /etc/passwd (执行一次)
②#awk ‘{print NR}’ /etc/passwd (执行N次,N为行数)
(一直到48(最后一行))
③#awk ‘END{print NR}’ /etc/passwd (执行一次,最后是总行数)
2.分析下面命令的执行结果
①#awk -F: ‘{print $NR}’/etc/passwd
(解析:第1行去第1个字段,第2行取第2个字段,第n行去第n个字段……)
②#awk -F: ‘{print NR, NF,
1,
NF, $(NF-1)}’ /etc/passwd
(输出每行的行号,字段数,用户名,最后一个字段,倒数第二个字段)
3.只显示df -h结果的第一列文件系统
# df -h|awk -F' ' '{print $1}' (注意指定分隔符为空白,默认就是空白)
4.显示passwd文件的第5行和第10行的行号和用户名
# cat passwd|awk -F: 'NR==5||NR==10{print NR,$1}'
练习:
1.使用NF变量显示passwd文件倒数第二列的内容
# cat passwd|awk -F: '{print $(NF-1)}'
2.显示passwd文件中第5到第10行的用户名
# cat passwd|awk -F: 'NR>=5&&NR<=10{print $1}'
3.显示passwd文件中第7列不是bash的用户名
# cat passwd|awk -F: '$7 ~/[^bash]$/{print $1}'
--》[^bash]中括号里的^表示取反。
或者:
# cat passwd|awk -F: '$7 !~/bash/{print $1}'
4.显示passwd文件中行号是5结尾的行号和行
# cat passwd|awk -F: 'NR%10==5{print NR,$0}'
# cat passwd|awk -F: 'NR ~/5$/{print NR,$0}'
5.用ifconfig只显示ip(不能使用tr或者cut命令)
# ifconfig|awk -F: '/inet addr/{print $2}'|awk '{print $1}'
192.168.1.147
127.0.0.1
# ifconfig |sed -n '/inet addr/p'|awk -F[:" "] '{print $13}'
6.使用awk显示eth0的入站流量和出站流量(字节)
# ifconfig eth0|awk -F'[: ]' '/RX bytes/{print $13,$19}'
# ifconfig eth0|tr -s ' '|awk -F'[: ]' '/RX bytes/{print $4,$9 }'
1025085 370703
7.使用awk命令统计以r开头的用户数目,显示如下效果
# cat passwd|awk -F: 'BEGIN{print "查找结果";i=0}/^r/{print $1;i++}END{print i}'
awk命令的引用shell变量
一、awk命令的引用shell变量
-v 引入shell变量
例1:
# name=haha
# echo|awk -v abc=$name '{print abc,$name}' --》引用awk变量无需加$
haha
# echo|awk -v abc=$name '{print $name}'
# echo|awk -v abc=$name '{print abc}'
haha
例2:
# name=haha;soft=xixi
# echo|awk -v abc=$name -v efg=$soft '{print abc,123}' --》123不用加引号就能输出
haha 123
==============
分析:
#!/bin/bash
awk -v var=$1 -F: '$1==var{print NR,$0}' /etc/passwd
[第1个$1是位置变量,是执行此脚本时后面接的参数;第2个$1指的是用户名。]
awk命令的函数
awk编程语言内置了很多函数。
length函数
例1:利用length计算字符数目的函数来检查有无空口令用户。
#awk -F: 'length($2)==0{print $1}' /etc/passwd /etc/shadow
例2:显示文件中超过50个字符的行。
# awk 'length($0)>50{print NR,$0}' /etc/passwd
3 rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
4 rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
7 mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
system函数
# cat list
xixi 123
haha 456
hehe 789
# awk '{system("useradd "$1)}' list
# ls /home
haha hehe hello xixi
# awk '{system("userdel -r "$1)}' list 【命令用双括号括起,后面有空格】
# ls /home
hello
练习:利用system函数给上述用户配置密码。
#awk '{system("useradd $1");print $1 "is add"}' list
#awk '{system("userdel -r "$1);print $1 "is deleted"}' list
#awk '{system("echo "$2"|passwd --stdin "$1)}' list
【命令用双括号括起,后面有空格】
awk命令的结构化语句
if语句
1.单分支
#awk -F: '{if($1 ~ /\<...\>/)print $0}' /etc/passwd
#awk -F: '{if($3 >= 500)print $1,$7}' /etc/passwd
2.双分支
#awk -F: '{if($3 != 0) print $1 ; else print $3}' /etc/passwd
3.多分支
#awk -F: '{if($1=="root") print $1;else if($1=="ftp") print $2;else if($1=="mail") print $3;else print NR}' /etc/passwd
例2:利用awk的if多重分支判断用户的类型,root显示为管理员 。
#awk -F: '{if($3==0) print $1,"管理员";else if($3>0 && $3<500) print $1,"系统用户";else if($3>=500 && $3 <= 60000) print $1,"普通用户";else print $1,"其它用户"}' /etc/passwd
例:利用awk的system命令在/tmp下建立/etc/passwd中与用户名同名的目录 。
#awk -F: '{system("mkdir /tmp/ "$1)}' /etc/passwd
练习1:用1条命令实现将指定目录下大于10K的对象复制到/tmp下(禁止使用find 和for) 。
#cp $(du -a /boot | awk '$1>10240{print $2}') /tmp
练习2:监控多台主机的磁盘分区一旦某台被监控主机的任一分区使用率大于80%, 就给root发邮件报警。
#!/bin/bash
warn=10
ip=(10.10.10.2 10.10.10.3)
for i in "${ip[@]}"
do
ssh root@$i df -Ph | tr -s " "|awk -v w=10 -F "[ %]" '/^\/dev/{if($5>w) print $1,$5"% useage is over 10%"}'>
alert
if [ -s alert ]
then
sed -i "1i $i" alert && mail -s "$i hd usage" root < alert
fi
done
练习3:检查/var/log/secure日志文件,如果有主机用root用户连接服务器的ssh服务失败次数超过10次(10次必须使用变量),就将这个IP地址加入/etc/hosts.deny文件拒绝其访问,如果这个IP已经存在就无需重复添加到/etc/hosts.deny文件(要求使用awk语句进行字符过滤、大小判断和变量赋值,禁止使用echo、sed、grep、cut、tr命令)
#/bin/bash
awk '/Failed password for root/{print $(NF-3)}' /var/log/secure|sort -nr| uniq -c > test --》sort 按降序排序,uniq -c统计次数
NUM=10
IP=$(awk '$1>num {print $2}' num=$NUM test) --》$1就是统计好的次数
for i in $IP
do
DENY=$(awk '$2==var {print $2}' var=$i /etc/hosts.deny)
if [[ -z $DENY ]]
then
awk '$2==var {print "sshd: "$2}' var=$i test >> /etc/hosts.deny
awk '$2==var {print "错误次数"$1,"拒绝"$2"访问"}' var=$i test
else
awk '$2==var {print "已经拒绝"$2"访问"}' var=$i test
fi
done
awk对行和列的累加
1.awk进行列求和
①统计/etc目录下以.conf结尾的文件的总大小
#find /etc/ -type f -name "*.conf" |xargs ls -l | awk '{sum+=$5} END{print sum}‘
②如果要匹配第一列的才累加,需要用到awk的数组和for循环(难点)
cat xferlog | awk '{print $7,$8}' | sort -n >/lianxi/123.txt
awk '{a[$1]+=$2}END{for(i in a) print i,a[i]}'/lianxi/123.txt | sort -rn -k2
--》a[$1]=a[$1]+$2--》a[172.16.1.3]=老的a[172.16.1.3]+对应次数
- xferlog是ftp服务器上的一个日志文件!
- awk里的数组支持shell里讲的关联数组!!
- sort -rn -k2是统计出下载量最大的ip并排序
③awk进行行求和
例1:
#echo 1 2 3 4 5 | awk '{for(i=1;i<=NF;i++) sum+=$i; print sum}'
例2:
#seq -s ' ' 100 | awk '{for(i=1;i<=NF;i++) sum+=$i; print sum}'
awk里面的数组是关联数组怎么理解:
练习:awk里如何使用数组来存放数据?
1.将所有的/etc/passwd所有的用户存放在user数组里。
# cat /etc/passwd|awk -F: '{user[$1]}'
解析:此时user[root]里面没有值,只是下标或者说索引变成了user[用户名]
# cat /etc/passwd|awk -F: '{user[$1]=$3}'
解析:此时,将$3的值(也就是uid)赋给user[$1]数组。
这样,就把用户和用户对应的uid关联起来了,用户名做下标关键字,uid做数组元素对应的值。
练习:awk里如何从数组里取出数据?
2.将user数组里的所有值取出来。
# cat /etc/passwd|awk -F: '{user[$1]=$3}END{for (i in user)print user[i],i}'
小结:
awk里关联数组难点的理解:
{a[$1]+=$2}
将$1对应的ip地址作为下标,将$2对应的大小赋值给下标为ip的元素。awk每读取一行就执行一次,重新又将$1对应的ip地址作为下标,执行a[$1]=a[$1]+$2,将上一行的a[$1]的值加上第2行$2值,实现累加的效果。但是ip地址还是那个ip地址,但是值已经累加了。
适用于:某一列不变,而对应的另一列的内容不同的场景。
练习:
username money
feng 100
feng 200
feng 360
li 100
li 150
zhang 90
zhang 88
统计每个人总共花了多少钱。并按总金额降序排序。
#cat money.txt|awk '{username[$1]+=$2}END{for(i in username)print i,username[i]}'|sort -nr -k2
awk里的关联数组之if判断
练习2:/etc/passwd里的所有的用户的uid存放到一个数组,如果用户输入的用户名在数组里,就输出这个用户对应的uid。
用户名做下标;uid做元素值。
答案:
#!/bin/bash
read -p "Please input the username:" u_name
cat /etc/passwd|awk -v U_name=$u_name -F: '{user[$1]=$3}END{if (U_name in user)print user[U_name]}'
补充:
三种获得uid大于500小于10000的方法:
# cat /etc/passwd|awk -F: '$3>500&&$3<10000{print $1,$3}'
# cat /etc/passwd|awk -F: '($3>500&&$3<10000){print $1,$3}'
# cat /etc/passwd|awk -F: '{if($3>500&&$3<10000)print $1,$3}'
sed 练习
1.sed取出/etc/passwd文件的第一列
2.sed将PATH环境变量中的冒号换成换行
3.sed将PATH环境变量斜杠/换成斜杠\
4.sed修改SELINUX配置文件从开启变成禁用(/etc/sysconfig/selinux)
5.去掉/etc/passwd文件中第二个地段的x
6.修改/etc/inittab文件里的3或者5修改为6
7.编写一个脚本实现修改ip地址:
7.1.提醒用户输入ip地址和子网掩码、dns、网关
7.2.需要判断新输入的ip地址是否有人使用,如果有人使用这个ip地址,就不能去修改ip,并且提示。
7.3.刷新网络服务,让新的ip地址生效。
答案:
1.# cat passwd|sed -r ‘s/(^[0-Z]+)(.*)/\1/’ –》\1表示第一个标签
2.# echo $PATH|sed ‘s/:/\n/g’
3.# echo $PATH|sed -r ‘s/\//\/g’
或者# echo $PATH|sed -r ‘s#/#\\#g’(以#作分界符)
4.# cat selinux|sed ‘/^SELINUX=/s/enforcing/disabled/g’
5.# awk -F: ‘{print $1”:”$3”:”$4”:”$6”:”$7}’ passwd
或者:# awk -F: ’ OFS=”:”{print $1,$3,$4,$5,$6,$7}’ passwd –》OFS指定输出分隔符
或者:# cat passwd|sed ‘s/:x:/::/g’
6.# cat inittab |sed -r ‘/^id/s/:[35]:/:6:/g’
7.
#!/bin/bash
read -p "Please input the ip:" IP
read -p "Please input the netmask:" MASK
read -p "Please input the dns server:" DNS
read -p "Please input the gateway:" GATEWAY
a=$(cat ifcfg-eth0|grep "IPADDR"|cut -d '=' -f2)
if [[ $IP == $a ]]
then
echo "The IP:$IP is exist!!!"
else
sed -i "{
/IPADDR/c IPADDR=$IP
/NETMASK/c NETMASK=$MASK
/DNS1/c DNS1=$DNS
/GATEWAY/c GATEWAY=$GATEWAY
}" /lianxi/ifcfg-eth0
echo "The IP is alter:$IP"
fi
shell考试题
1简答:
在bash中,在一条命令后面加入”&>/dev/null” 意味着什么?$?、$$、$0、$1、$@、$#分别表示什么意思。
答:&>/dev/null就是放入垃圾桶(黑洞文件),消除多余的输出信息。
$?:上一条命令的返回值。正确执行为0;
$$:当前shell的进程号
$0:当前行的全部字段信息
$1:第一个字段值
$@:数组里的全部元素
$#:数组的总元素数
答:
#!/bin/bash
cat access.log |sort|uniq -c|sort -nr|awk '{sum+=$1}END{print "总访问次数:"sum}'
cat access.log |sort|uniq -c|sort -nr|awk 'NR<=5{print $0}'
执行结果:
3(功能2、3未实现)
答:
#!/bin/bash
menu(){
echo "**********************"
echo -e "\t1.备份/var/log目录"
echo -e "\t2.指定备份文件路径备份"
echo -e "\t3.根据条件查找文件备份"
echo -e "\t4.退出"
echo "**********************"
}
main(){
while :
do
clear
menu
read -p "Please input the choise:" cho
case $cho in
1) #备份/var/log目录
a=$(date +%F-%H:%M:%S)
[ -d /kaoshi/bak/log ]||mkdir /kaoshi/bak/log
tar -czvf /kaoshi/bak/log/$a-log.tar.gz /var/log/* &>/dev/null
echo "备份完毕!"&& ls /kaoshi/bak/log
find /kaoshi/bak/log -mtime +7 -type f -exec rm -rf {} \; &>/dev/null
;;
2) #指定备份文件路径备份
today=$(date +%F)
a=$(date +F-%H:%M:%S)
[ -d /kaoshi/bak/$today ]||mkdir /kaoshi/bak/$today --》双引号
tar -czvf /kaoshi/bak/2016-07-14/pass_$a-log.tar.gz /var/log &>/dev/null
echo "备份完毕!"&& ls /kaoshi/bak/$today
;;
3) #根据条件查找文件备份(case)
read -p "请输入最近几天进行查找:" day
[ -d /kaoshi/bak/find ]||mkdir /kaoshi/bak/find
find /kaoshi/bak/log -type f -mtime -$day >>/kaoshi/bak/find.txt
if (( $?==0 )) --》find命令的返回值一直是0!!
then
find /kaoshi/bak/log -type f -mtime -$day -exec cp {} /kaoshi/bak/find \;
else
echo "对不起,没有找到对应文件."
fi
;;
4) #退出
exit
;;
*)
echo "Please input 1-4!!!"
;;
esac
read -p "Please input anykey to continue..."
done
}
main
4
答:
#!/bin/bash
read -p "Please input the sorce:" so
if (( $so>=90&&$so<=100 ))
then
echo "good job,may be you can try join alibaba"
elif (( $so>=80&&$so<=89 ))
then
echo "nice,may be you can try join tencent"
elif (( $so>=60&&$so<=79 ))
then
echo "come on,baby!may be you can try join facebook"
elif (( $so>=0&&$so<=59 ))
then
echo "keep on fighting,may be you can try join google"
else
echo "Please input 0-100!!!"
fi
5
D.最后显示所有新建的用户的名字和uid、gid、家目录、shell。
答:
#!/bin/bash
read -p "Please input the name:" name
read -p "Please input the number:" num
read -p "Please input the password:" pass
for i in `seq $num`
do
id $name$i &>/dev/null|useradd $name$i
echo "$pass"|passwd $name$i --stdin &>/dev/null
done
6
答:
#!/bin/bash
cat /etc/passwd|awk -F: '$3>500&&$3<5000{print "username:"$1,"uid is "$3,"gid is "$4}'
7
答:
#!/bin/bash
cat web.log|awk -F '/' '{print $3}'|sort -nr|uniq -c
8
答:
#!/bin/bash
names=($(cat singers.txt))
songs=($(cat songs.txt))
nnames=${#names[@]}
nsongs=${#songs[@]}
echo "共有$nnames位歌手:${names[@]}"
echo "共有$nsongs首歌:${songs[@]}"
name1=$((RANDOM%$nnames))
song1=$((RANDOM%$nsongs))
for i in $(seq 3 -1 1)
do
echo -e "\t\t$i"
sleep 1
done
echo -e "\n\t\t有请${names[$name1]}演唱《${songs[$song1]}》"
#将已经选中的歌和人追加到pass文件里,并且删除用过的数组元素
echo "${names[name1]}" >>pass_singers.txt
echo "${songs[song1]}" >>pass_songs.txt
unset names[name1]
unset songs[song1]
#重新定义原来的两个数组,并且当数组元素为0时,更新数组;每次选完后更新文件
echo "${names[@]}" >singers.txt
if ((${#names[@]}==0))
then
mv pass_singers.txt singers.txt
echo "Update singers OK!"
fi
echo "${songs[@]}" >songs.txt
if ((${#songs[@]}==0))
then
mv pass_songs.txt songs.txt
echo "Update songs OK!"
fi
9
答:
#!/bin/bash
menu(){
echo "***********************"
echo -e "\t1.配置主机名"
echo -e "\t2.配置ip"
echo -e "\t3.查看ip和主机名"
echo -e "\t4.退出"
echo "***********************"
}
main(){
while :
do
clear
menu
read -p "请输入你的选择:" choice
case $choice in
1)
#临时修改主机名
read -p "请输入你想要的主机名:" name
hostname $name
#永久修改主机名
#read -p "请输入你想要的主机名:" name2
#vim /etc/sysconfig/network|sed 's/HOSTNAME=liupeng/HOSTNAME=$name2/g'
;;
2)
read -p "请输入你想要的IP" IP
ifconfig eth0 $IP
service network restart &>/dev/null
;;
3)
ifconfig|tr -s ' '|awk -F "[: ]" '/Bcast/{print $4}'
hostname
;;
4)
exit
;;
*)
echo "请输入1-4的数!!"
esac
read -p "请按任意键继续..."
done
}
main
10(功能5未全实现)
答:
#!/bin/bash
menu(){
echo "***********************"
echo -e "\t1.add user"
echo -e "\t2.delete user"
echo -e "\t3.query user information"
echo -e "\t4.reset user's password"
echo -e "\t5.modify user's information"
echo -e "\t6.exit"
echo "***********************"
}
menu2(){
echo "***********************"
echo -e "\t1.update uid"
echo -e "\t2.update gid"
echo -e "\t3.update shell"
echo -e "\t4.update home"
echo -e "\t5.exit"
echo "***********************"
}
modify(){
while :
do
clear
menu2
read -p "请输入你的选择:" xuanze
case $xuanze in
1)
read -p "Please input the name:" na
if (id $na &>/dev/null)
then
read -p "Please input the uid:" uid
usermod -u $uid -o 用户名$na
echo "update uid success!"
else
echo "no exits!"
fi
;;
2)
#groupmod -g
;;
3)
#??? usermod -d 目录路径 -u uid
;;
4)
#??? usermod
;;
5)
exit
;;
*)
echo "Please input 1-5!!!"
;;
esac
read -p "Please input anykey to continue ..."
done
}
main(){
while :
do
clear
menu
read -p "请输入你的选择:" choice
case $choice in
1)
read -p "Please input the name:" name
if (id $name &>/dev/null)
then
echo "exit!"
else
useradd $name &>/dev/null
echo "create success!"
fi
;;
2)
read -p "Please input the name:" b
if (id $b &>/dev/null)
then
userdel -r $b
echo "delete success!"
else
echo "no exits!"
fi
;;
3)
read -p "Please input the name:" c
if (id $c &>/dev/null)
then
id $c
else
echo "no exists!"
fi
;;
4)
read -p "Please input the name:" d
if (id $d &>/dev/null)
then
read -p "Please input the password:" e
echo $e|passwd $d --stdin &>/dev/null
echo "uptate password success!"
else
echo "no exits!"
fi
;;
5)
modify
;;
6)
exit
;;
*)
echo "请输入1-6的数!!"
;;
esac
read -p "请按任意键继续..."
done
}
main
11
答:
#!/bin/bash
[ -d /yum ]||mkdir /yum
mount /dev/cdrom /yum &>/dev/null
cd /etc/yum.repos.d
cat >local.repo<<EOF
[local_yum]
name=local yum
baseurl=file:///yum
enabled=1
gpgcheck=0
EOF
yum clean &>/dev/null
echo "yum created successful!!!"
#安装mysql服务和启动mysql
yum install mysqld -y
service mysqld start
#追加命令到样板文件即可
echo "service mysqld start" >>/etc/skel/.bashrc
12
答:
#!/bin/bash
ps aux >aux.txt
echo "CPU使用率前十:"
cat aux.txt |sort -nr -k3|awk 'NR>=2&&NR<=10{print $1,$2,$3"%"}'
echo "内存使用率前十:"
cat aux.txt |sort -nr -k4|awk 'NR<=10{print $1,$2,$4"%"}'
13
答:
#/bin/bash
a=$(netstat -anplt|tr -s ' '|awk -F "[ :]" '/3306/{print $4}')
if ( lsof -i:3306 )
then
echo "监听地址:$a"
else
service mysqld start
fi
system tools(菜单 main)
***************system tools*************
1.build local yum
2.build ftp server
3.user management
4.memory statistic
5.cpu statistic
6.disk statistic
7.ftp server monitor
8.exit
******************************************
答案:
#!/bin/bash
menu(){
echo "************System Tools**********"
echo -e "\t1.build local yum"
echo -e "\t2.build ftp server"
echo -e "\t3.user management"
echo -e "\t4.memory statistic"
echo -e "\t5.cpu statistic"
echo -e "\t6.disk statistic"
echo -e "\t7.ftp server monitor"
echo -e "\t8.exit"
echo "**********************************"
}
main(){
while :
do
clear
menu
source monitor_system.sh
read -p "Please input your choise:" choise
case $choise in
1)
bash yum.sh
;;
2)
bash ftpbuild.sh
;;
3)
bash useradd.sh
;;
4)
monitor_mem
;;
5)
monitor_cpu
;;
6)
monitor_disk
;;
7)
w
;;
8)
exit
;;
*)
echo "Please input the number of 1-8..."
;;
esac
read -p "Please input anykey to continue..."
done
}
main
猜商品价格游戏RANDOM,while.note
练习:猜商品价格游戏
猜唐僧的紫金钵价值多少~
①通过变量RANDOM获得价格
②提示用户猜测并记录次数,猜中后退出循环
分析:随机产生价格(1-100),给与提醒,价格高了/低了,记录猜的次数,如果猜的次数大于10次,输出you are bajie;5次,you are wukong;1次,you are rulai。并且猜中后退出循环,没有猜中就一直猜。。
答案:
#!/bin/bash
time=0
a=$((RANDOM%100)) --》产生0到99的自然数。
while :
do
read -p "Please input the price between 1 and 100:" price
((time++))
if ((price==a))
then
echo "Bingo!!You guess it!"
echo "The time that you guess is :$time"
break
elif ((price>a))
then
echo "The $price is 高了!!"
else
echo "The $price is 低了!!"
fi
done
if ((time==1))
then
echo "You are rulai!"
elif ((time<5 && time>1))
then
echo "You are wukong!!"
elif ((i<=10))
then
echo "You are bajie!!"
else
echo "You are loser..."
fi
查找出uid大于X的用户(for循环)
查找出uid大于500的用户。使用for循环。
#!/bin/bash
uid=(`cat /etc/passwd|awk -F: '{print $3}'`)
name=(`cat /etc/passwd|awk -F: '{print $1}'`)
for i in `seq ${#uid[@]}`
do
if (( ${uid[i-1]}>500 ))
then
echo "${uid[i-1]},${name[i-1]}"
fi
done
方法2:用正则找出大于500的用户:
cat /etc/passwd|egrep "5[0-9]{2}|[6-9]{3}"
搭建本地yum源
#!/bin/bash
[ -d /yum ]||mkdir /yum --》/yum不存在的时候才创建。
mount /dev/cdrom /yum &>/dev/null
cd /etc/yum.repos.d
cat >local.repo <<EOF
[local_yum]
name=local yum
baseurl=file:///yum
enabled=1
gpgcheck=0
EOF
yum clean &>/dev/null
echo "yum created successful!!"
PS:
搭建本地yum源:
1.放入系统光盘
2.新建一个目录/yum
3.挂载镜像光盘到/yum
mount /dev/cdrom /yum
补充:
4.修改yum的配置文件
#cd /etc/yum.repos.d
#vim local.repo
[local_yum]
name=local yum
baseurl=file:///yum –》镜像的挂载出处!!
enabled=1
gpgcheck=0
5.清除yum缓存
yum clean all
#6.将selinux关闭
getenforce –》查看selinux状态
setenforce 0 –》临时关闭
7.安装软件
#yum install python-ipython
当前eth接口的有效ip和有效网关
编写脚本实现显示当前主机eth接口的有效IP和有效网关,要求显示结果如下图所示(多使用正则表达式,少用cut和tr)
分析:route -n–》看网关,ifconfig–》看ip,
答案:
[cat /lianxi/eth01.sh]
#!/bin/bash
ifconfig|egrep "([1-9]|[1-9][0-9]|1[0-9][0-9]|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}"|head -n +2|tr -s " " ":"|cut -d":" -f4,6,8|tr -s ":" " " >eth01.txt
n=0
for i in $(<eth01.txt)
do
((n++))
if (( n==1 ))
then
(echo $i|egrep "([1-9]|[1-9][0-9]|1[0-9][0-9]|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}"&>/dev/null)&&echo "eth0:$i"||echo "no IP"
elif (( n==4 ))
then
(echo $i|egrep "([1-9]|[1-9][0-9]|1[0-9][0-9]|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}"&>/dev/null)&&echo "eth1:$i"||echo "no IP"
fi
done
route -n|tail -n 1 >GATEWAY.txt
cat GATEWAY.txt|while read a IP c d e f g ETH
do
if ( echo $IP|egrep "([1-9]|[1-9][0-9]|1[0-9][0-9]|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}"&>/dev/null )
then
echo "gateway: $IP ($ETH)"
else
echo "gateway: NULL"
fi
done
当前主机中哪些是普通用户,哪些是系统用户.note
分析当前主机中所有用户,哪些是普通用户,哪些是系统用户。
分析:
看 passwd文件的UID,uid>500则为普通用户,uid<500则为系统用户,
uid怎么从passwd文件里弄出来,uid>500的用户怎么弄出来,怎么嵌套进循环里。
答案:
#!/bin/bash
cat /etc/passwd|tr ":" " "|while read username x uid gid --》用户名给username变量,x给x变量,uid给uid变量,其他的给gid这个变量,while取出来是一行一行的取出。
do
if ((uid>500))
then
echo "$username is general user."
elif ((uid==0))
then
echo "$username is super user."
else
echo "$username is system user."
fi
done
(闪烁功能:#echo -e"\e[5;33mHello,Word\e[0m"
而且是显示黄色,并且闪烁)
点歌程序脚本
点歌程序:v2
1.准备歌手名单,曲库;
2.随机抽歌手,随机抽歌,输出谁要唱什么歌;
3.抽过的歌手,已经唱过的歌手和歌曲都不能再出现。
答案:
#!/bin/bash
songs=($(cat songs.txt))
names=($(cat singer.txt))
nsong=${#songs[@]} --》统计数组元素的个数
nname=${#names[@]}
echo "共有$nsong首歌:${songs[@]}" --》显示全部数组元素
echo "共有$nname位歌手:${names[@]}"
name1=$((RANDOM%$nname)) --》随机选取
song1=$((RANDOM%$nsong))
for i in $(seq 3 -1 1) --》倒计时三秒效果
do
echo -e "\t\t$i"
sleep 1
done
echo -e "\n\t\t有请 ${names[$name1]} 演唱 <<${songs[$song1]}>>"
#将已经选中的追加到pass文件里,并且删除用过的数组元素
echo "${names[name1]}" >>pass_singer.txt
echo "${songs[song1]}" >>pass_songs.txt
unset names[name1]
unset songs[song1]
#重新定义原来的两个数组,并且当数组元素为0时,更新数组
echo "${names[@]}" >singer.txt
if ((${#names[@]}==0))
then
mv pass_singer.txt singer.txt
echo "Update singer is OK!"
fi
echo "${songs[@]}" >songs.txt
if ((${#songs[@]}==0))
then
mv pass_songs.txt songs.txt
echo "Update songs is OK!"
fi
效果:
给登录到当前主机的所有非root用户终端发送一句话
给登录到当前主机的所有非root用户终端发送一句话:“用户名:Hi,I’m Root!”
答案:
#!/bin/bash
w|tail -n +3|while read user TTY other --》w命令显示连接到本机的所有用户
do
if [[ "$user" != "root" ]]
then
echo "Hello $user,I am Root!" >/dev/$TTY
fi
done
执行结果:
另起一个终端,
函数 菜单 main
监控脚本:
1.显示内存的使用 monitor_mem()
2.显示cpu的使用 monitor_cpu
3.显示磁盘分区的使用情况 monitor_disk()
主要是/和/boot分区
4.显示内存使用率最大的5个进程 monitor_mem5()
5.显示cpu使用率最大的5个进程 monitor_process5()
分析:
free -m:看内存的使用
top -n 1:top命令仅执行一次(显示的少,不是所有的进程!、
df -Th:看磁盘空间
ps aux(所有进程一瞬间的快照)
答案:
#!/bin/bash
monitor_mem(){
echo "****************mem********************"
free -m
echo "***************************************"
}
monitor_cpu(){
echo "***************cpu*********************"
top -n 1|egrep "^Cpu"
uptime|cut -d, -f4,5,6
echo "***************************************"
}
monitor_disk(){
echo "*************disk partition************"
df -Th|grep "/$"
df -Th|grep "/boot"
echo "***************************************"
}
monitor_cpu5(){
echo "************cpu5***********************"
ps aux|tail -n +2|sort -k3 -nr|head -5 >cpu5.txt
#awk 'BEGIN(i=1){print i;print "pid:"$2,"memory use:"$6,"program name:"$11;i++}' cpu5.txt
program_name=($(cat cpu5.txt|awk '{print $11}'))
cpu_use=($(cat cpu5.txt|awk '{print $3}'))
rm -rf cpu5.txt
for i in {1..5}
do
echo "$i program name is ${program_name[i-1]} memory use:${cpu_use[i-1]}"
done
echo "***************************************"
}
monitor_mem5(){
echo "************mem5***********************"
ps aux|tail -n +2|sort -k6 -nr|head -5 >mem5.txt
program_name=($(cat mem5.txt|awk '{print $11}'))
memory_size=($(cat mem5.txt|awk '{print $6}'))
rm -rf mem5.txt
for i in {1..5}
do
echo "$i program name is ${program_name[i-1]} memory use:${memory_size[i-1]}"
done
echo "***************************************"
}
monitor_mem
monitor_cpu
monitor_disk
monitor_cpu5
monitor_mem5
监控脚本的菜单和main函数的实现
#!/bin/bash
menu(){
echo -e "1.\tdisplay memory statistics"
echo -e "2.\tdisplay cpu statistics"
echo -e "3.\tdisplay disk partiton statistics"
echo -e "4.\tdisplay cpu top5 statistics"
echo -e "5.\tdisplay mem top 5 statistics"
}
main(){
while :
do
clear
menu
source monitor_system.sh
read -p "Please input your choice option:" choice
case $choice in
1)
monitor_mem
;;
2)
monitor_cpu
;;
3)
monitor_disk
;;
4)
monitor_cpu5
;;
5)
monitor_mem5
;;
6)
exit
;;
*)
echo "Please input 1-6 !!!"
;;
esac
read -p "Please input anykey to continue..."
done
}
main
监控脚本
大练习:
编写一个监控脚本,监控172.16.1.* ftp服务器的ftp服务是否正在运行,而且每秒监控一次,一旦发现ftp服务器没有运行了,马上报警并输出warnning!ftp server is down!!
需求分析:
1.nc
2.死循环–》while
3.判断if
如果考虑一直往一个文件里写,需要考虑磁盘空间的问题,会把磁盘空间耗光。
输出的时候加一个日期。
4.如果down机,需要统计出是什么时候down机的。
使用一个文件记录down机时间,判断这个文件里是否有内容,如果有说明已经记录了,就不记录。
5.down机时间的统计、down机次数的统计
例如:累计down5次,明细:
1 10分钟 从2015-5-15 12:03
2 50分钟 从2015-5-16 18:03
答案:
# vim jiankong.sh
#!/bin/bash
################主菜单
menu(){
#!/bin/bash
################主菜单
menu(){
clear
echo -e "\t\t\e[31m **** ****\e[0m\e[5;32m 监控系统\e[0m\e[31m **** ****\e[0m"
echo -e "\t\t\e[35m **** **** 3.exit **** ****\e[0m"
}
##################次级菜单
menu2(){
echo -e "\t\t\e[5;31m **** **** 监控系统 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 1.查询监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 2.删除监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 3.备份监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 4.返回上一级 **** ****\e[0m"
}
###################监控日志查询清空与备份
########监控程序
jiankong(){
######网址判断
read -p "请输入你想监控的网址" ip
while :
do
echo "$ip">>ip.txt
pp=`cat ip.txt|tail -1|egrep "\b([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-9])(\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}\b" |awk -F. 'NF<=4'|wc -l`
if (( pp==0 ))
then
read -p "请您输入有效的IP地址:" ip
else
>ip.txt
break;
fi
done
n=0 ######监控
but_q=null
while :
do
a=`date +%F`
b=`date "+%F %H:%M:%S"`
nc -z $ip 21 &>/dev/null
if (( $? == 0 ))
then
t=`cat downtime.txt|head -1`
count=`cat downtime.txt|wc -l`
if (( ${count} != 0 ))
then
((n++))
echo " $ip 运行监控程序后第$n次down机,共${count}秒,从$t到$b">>/lianxi/jiankong/bak/log${a}.txt
>downtime.txt
else
echo -e "\e[31m正在监控中,$ip ftp server is running...,input 'q' to return menu\e[0m"
read -s -n1 -t1 but_q
if [[ "$but_q" = "q" ]]
then
read -n1 -t3 -s -p "Do you want to quit to menu [Y/N]?" answer
case $answer in
Y|y)
break;;
N|n)
continue
;;
*)
continue
;;
esac
fi
fi
else
echo -e "\e[31mwarnning!!the ${ip} ftp server is down!\e[0m"
echo -e "\e[031m input 'q' to return the menu!\e[0m"
echo "$b">>downtime.txt
read -s -n1 -t1 but_q
if [[ "$but_q" = "q" ]]
then
echo
read -n1 -t3 -s -p "Do you want to quit to menu[Y/N]?" answer
case $answer in
Y|y)
break;;
N|n)
continue
;;
*)
continue
;;
esac
fi
fi
sleep 1
done
}
###################备份主函数
bakmain(){
clear
while :
do
menu2
read -p"please choose the option(1-4):" cho2
case $cho2 in
1)
chk
;;
2)
del
;;
3)
tar2
;;
4)
break;;
*)
echo "your input is wrong,please try again!"
;;
esac
clear
done
}
#############主函数
main(){
clear
while :
do
menu
read -p"please choose the option(1-3):" cho
case $cho in
1)
jiankong
;;
2)
bakmain
;;
3)
echo -e "\e[31mthank you for use the system!\e[0m"
break;;
*)
echo -e "\e[31myour inupt is wrong,please try again!\e[0m"
;;
esac
done
}
###############chk查看
chk(){
k=`ls -l /lianxi/jiankong/bak|wc -l`
while :
do
if (( k == 1 ))
then
echo -e "\e[31m系统没有查找到任何监控日志文件!\e[0m"
read -p"按回车键返回上一层"
break;
else
echo -e "\e[31m这里是所有的日志文件:\e[0m"
ls /lianxi/jiankong/bak
read -p "查询请输入1,退出请输入2:" an
if [[ $an == "1" ]]
then
while :
do
read -p "请输入你要具体要查询的日志文件日期(year-month-day:2000-02-01):" day
if [ -f /lianxi/jiankong/bak/log${day}.txt ]
then
echo -e "\e[31mlog${day}的内容如下:\e[0m"
cat /lianxi/jiankong/bak/log${day}.txt
read -p "按回车键返回"
break;
else
echo "你输入的文件格式有问题或者不存在,请重新输入!"
fi
done
elif [[ $an == "2" ]]
then
break;
else
echo -e "\e[31m您的输入错误,请重新输入(1或2):\e[0m"
fi
fi
done
}
##############del删除
del(){
k=`ls -l /lianxi/jiankong/bak|wc -l`
while :
do
if (( k == 1 ))
then
echo -e "\e[31m系统没有查找到任何监控日志文件!\e[0m"
read -p"按回车键返回上一层"
break;
else
echo -e "\e[31m这里是所有的日志文件:\e[0m"
ls /lianxi/jiankong/bak
read -p"删除文件请输入1,退出请输入2:" an
if [[ $an == "1" ]];then
k=`ls -l /lianxi/jiankong/bak|wc -l`
if ((k ==1))
then
read -p "所有文件都已被删除!请按回车键返回"
else
read -p"请输入你想删除的文件日期(year-month-day:2000-02-01):" day
while :
do
if [ -f /lianxi/jiankong/bak/log${day}.txt ]
then
read -p"你确认删除?一旦删除将无法还原(y/n):" an
if [[ $an == "y" ]]
then
rm -rf /lianxi/jiankong/bak/log${day}.txt
echo "delete is ok!"
read -p "按回车键返回"
break;
else
break;
fi
else
echo "你输入的文件格式不对或者不存在,请重新输入!"
fi
done
fi
elif [[ $an == "2" ]];then
break;
else
echo -e "\e[31m您的输入有误,请重新输入\e[0m"
fi
fi
done
}
##############备份
menu
read -p"please choose the option(1-3):" cho
case $cho in
1)
jiankong
;;
2)
bakmain
;;
echo -e "\t\t\e[5;31m **** **** 监控系统 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 1.查询监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 2.删除监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 3.备份监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 4.返回上一级 **** ****\e[0m"
}
###################监控日志查询清空与备份
########监控程序
jiankong(){
######网址判断
read -p "请输入你想监控的网址" ip
while :
do
echo "$ip">>ip.txt
pp=`cat ip.txt|tail -1|egrep "\b([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-9])(\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}\b" |awk -F. 'NF<=4'|wc -l`
#pp=`cat ip.txt|tail -1|egrep "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-9])(\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"`
if (( pp==0 ))
then
read -p "请您输入有效的IP地址:" ip
else
>ip.txt
break;
fi
done
n=0 ######监控
but_q=null
while :
do
a=`date +%F`
#!/bin/bash
################主菜单
menu(){
clear
echo -e "\t\t\e[31m **** ****\e[0m\e[5;32m 监控系统\e[0m\e[31m **** ****\e[0m"
echo -e "\t\t\e[33m **** **** 1.启动监控程序 **** ****\e[0m"
echo -e "\t\t\e[34m **** **** 2.监控日志管理 **** ****\e[0m"
echo -e "\t\t\e[35m **** **** 3.exit **** ****\e[0m"
}
##################次级菜单
menu2(){
echo -e "\t\t\e[5;31m **** **** 监控系统 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 1.查询监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 2.删除监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 3.备份监控日志 **** ****\e[0m"
echo -e "\t\t\e[31m **** **** 4.返回上一级 **** ****\e[0m"
}
###################监控日志查询清空与备份
########监控程序
jiankong(){
######网址判断
read -p "请输入你想监控的网址" ip
while :
do
echo "$ip">>ip.txt
pp=`cat ip.txt|tail -1|egrep "\b([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-9])(\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}\b" |awk -F. 'NF<=4'|wc -l`
#pp=`cat ip.txt|tail -1|egrep "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-9])(\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"`
if (( pp==0 ))
then
read -p "请您输入有效的IP地址:" ip
else
>ip.txt
break;
fi
done
n=0 ######监控
but_q=null
while :
do
a=`date +%F`
else
>ip.txt
break;
fi
done
n=0 ######监控
but_q=null
while :
do
a=`date +%F`
b=`date "+%F %H:%M:%S"`
nc -z $ip 21 &>/dev/null
if (( $? == 0 ))
then
t=`cat downtime.txt|head -1`
count=`cat downtime.txt|wc -l`
if (( ${count} != 0 ))
then
((n++))
echo " $ip 运行监控程序后第$n次down机,共${count}秒,从$t到$b">>/lianxi/jiankong/bak/log${a}.txt
>downtime.txt
else
echo -e "\e[31m正在监控中,$ip ftp server is running...,input 'q' to return menu\e[0m"
read -s -n1 -t1 but_q
if [[ "$but_q" = "q" ]]
then
read -n1 -t3 -s -p "Do you want to quit to menu [Y/N]?" answer
case $answer in
Y|y)
break;;
N|n)
continue
;;
*)
continue
;;
esac
fi
fi
else
echo -e "\e[31mwarnning!!the ${ip} ftp server is down!\e[0m"
echo -e "\e[031m input 'q' to return the menu!\e[0m"
echo "$b">>downtime.txt
read -s -n1 -t1 but_q
if [[ "$but_q" = "q" ]]
then
echo
read -n1 -t3 -s -p "Do you want to quit to menu[Y/N]?" answer
case $answer in
Y|y)
break;;
N|n)
continue
;;
*)
continue
;;
esac
fi
fi
sleep 1
done
}
###################备份主函数
bakmain(){
clear
while :
do
menu2
read -p"please choose the option(1-4):" cho2
case $cho2 in
1)
chk
;;
2)
del
;;
3)
tar2
;;
4)
break;;
*)
echo "your input is wrong,please try again!"
;;
esac
clear
done
}
#############主函数
main(){
clear
while :
do
menu
read -p"please choose the option(1-3):" cho
case $cho in
1)
jiankong
;;
2)
bakmain
;;
3)
echo -e "\e[31mthank you for use the system!\e[0m"
break;;
*)
echo -e "\e[31myour inupt is wrong,please try again!\e[0m"
;;
esac
done
}
###############chk查看
chk(){
k=`ls -l /lianxi/jiankong/bak|wc -l`
while :
do
if (( k == 1 ))
then
echo -e "\e[31m系统没有查找到任何监控日志文件!\e[0m"
read -p"按回车键返回上一层"
break;
else
echo -e "\e[31m这里是所有的日志文件:\e[0m"
ls /lianxi/jiankong/bak
read -p "查询请输入1,退出请输入2:" an
if [[ $an == "1" ]]
then
while :
do
read -p "请输入你要具体要查询的日志文件日期(year-month-day:2000-02-01):" day
if [ -f /lianxi/jiankong/bak/log${day}.txt ]
then
echo -e "\e[31mlog${day}的内容如下:\e[0m"
cat /lianxi/jiankong/bak/log${day}.txt
read -p "按回车键返回"
break;
else
echo "你输入的文件格式有问题或者不存在,请重新输入!"
fi
done
elif [[ $an == "2" ]]
then
break;
else
echo -e "\e[31m您的输入错误,请重新输入(1或2):\e[0m"
fi
fi
done
}
##############del删除
del(){
k=`ls -l /lianxi/jiankong/bak|wc -l`
while :
do
if (( k == 1 ))
then
echo -e "\e[31m系统没有查找到任何监控日志文件!\e[0m"
read -p"按回车键返回上一层"
break;
else
echo -e "\e[31m这里是所有的日志文件:\e[0m"
ls /lianxi/jiankong/bak
read -p"删除文件请输入1,退出请输入2:" an
if [[ $an == "1" ]];then
k=`ls -l /lianxi/jiankong/bak|wc -l`
if ((k ==1))
then
read -p "所有文件都已被删除!请按回车键返回"
else
read -p"请输入你想删除的文件日期(year-month-day:2000-02-01):" day
while :
do
if [ -f /lianxi/jiankong/bak/log${day}.txt ]
then
read -p"你确认删除?一旦删除将无法还原(y/n):" an
if [[ $an == "y" ]]
then
rm -rf /lianxi/jiankong/bak/log${day}.txt
echo "delete is ok!"
read -p "按回车键返回"
break;
else
break;
fi
else
echo "你输入的文件格式不对或者不存在,请重新输入!"
fi
done
fi
elif [[ $an == "2" ]];then
break;
else
echo -e "\e[31m您的输入有误,请重新输入\e[0m"
fi
fi
done
}
##############备份
tar2(){
k=`ls -l /lianxi/jiankong/bak|wc -l`
while :
do
if (( k == 1 ))
then
echo -e "\e[31m系统没有查找到任何监控日志文件!\e[0m"
read -p"按回车键返回上一层"
break;
else
echo "这里是所有的日志文件:"
ls /lianxi/jiankong/bak
read -p "备份文件请输入1,退出请输入2:" an
if [[ $an == "1" ]];then
read -p "请输入你想备份的日志文件(year-month-day:2000-02-01):" day
while :
do
if [ -f /lianxi/jiankong/bak/log${day}.txt ]
then
cd /lianxi/jiankong/bakup
tar -czvf ${day2}.tar.gz /lianxi/jiankong/bak/log${day2}.txt &>/dev/null
echo "${day2} 备份成功!"
read -p"按任回车键返回"
else
read -p"你输入的文件格式不对或者不存在,请重新输入:" day
fi
done
elif [[ $an == "2" ]];then
break;
else
read -p"你的输入有误,请重新输入:" an
fi
fi
done
}
main
监控内存的使用情况
练习2:
监控内存的使用情况,一旦内存的可用空间低于800M就在屏幕上输出“your system is less than 800M,you need to do something to improve memory size”(用free -m 命令即可)
答案:
# a=$(free -m|grep "Mem"|awk '{print $4}')
# [ $a -lt 800 ]&&echo "your system is less than 800M"
free -m --》以M为单位显示内存的使用情况。
监听mysql服务是否开启
练习:
1.判断内核版本,如果大于2.6,显示“内核版本:版本,否则显示内核版本太低,无法继续”(uname -r)
2.检查mysqld服务是否开启,如果开启显示如下内容:
监听地址:0.0.0.0:3306
如果没有开启,将mysqld服务启动
(netstat -anplut|grep 3306)
(lsof -i:3306)
答案:
1.
#/bin/bash
a=$(uname -r|awk -F'.' '{print $1"."$2}')
if [[ $a>2.6 ]]
then
echo "内核版本:$a"
else
echo "内核版本太低,无法继续!"
fi
2.
#/bin/bash
a=$(netstat -anplt|awk '/3306/{print $5}')
if ( lsof -i:3306 )
then
echo "监听地址:$a"
else
service mysqld start
fi
netstat命令(-anplut)
netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检查本机各端口的网络连接情况。
netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP监听,进程内存管理的相关报告。
命令参数:
-a 显示所有连线中的socket all
-c 持续列出网络状态 continue
-C 显示路由器配置的快取信息 cache
-e 显示网络其他相关信息 extend
-F 显示FIB fib
-g 显示多重广播功能群组组员名单 groups
-h 显示帮助 help
-i 显示网络界面信息表单 interfaces
-l 显示监控中的服务器的socket listening
-M 显示伪装的网络连线 masquerade
-n 直接使用ip地址,而不通过域名服务器 numeric
-N 显示网络硬件外围设备的符号连接名称 netlink或symbolic
-o 显示计时器 timers
-p 显示正在使用socket的程序识别码和程序名称 programs
-r 显示route table route
-s 显示网络工作信息统计表 statistice
-t 显示TCP传输协议的连线情况 tcp
-u 显示UDP传输协议的连线情况 udp
-v 显示指令执行进程 verbose
-V 显示版本信息 version
-w 显示RAW传输协议的连线状态 raw
-x 此参数的效果和指定”-A unix”参数相同 unix
-ip 此参数的效果和指定”-A inet”参数相同 inet
截取本机上所有网卡的ip地址和子网、网关
练习:
1.截取出本机上所有网卡的ip地址和子网掩码、默认网关
2.格式如下:
eth0 ip adreess is 172.16.1.1/16
eth1 ip adreess is 173.168.1.1/16
default gateway is 173.168.20.20
dns servers are 114.114.114.114 219.146.1.66
#得到eth0和eth1的名字:
# ip add|grep "mtu"|awk '{print $2}'|tr -d :
#得到eth0的ip地址:
#ifconfig eth0|grep "inet addr"|tr -s ':' ' '|cut -d' ' -f4
#得到eth1的ip地址:
#ifconfig eth1|grep "inet addr"|tr -s ':' ' '|cut -d' ' -f4
#得到默认网关:
# route -n|grep "^192"|awk '{print $2}'
#获得DNS:
# cat /etc/resolv.conf |grep " DNS1"|tr = ' '|awk '{print $3}'
或
# cat /etc/resolv.conf |grep " DNS1"|tr = ' '|cut -d ' ' -f3
练习 :
1.只显示/boot目录下所有对象的实际空间,并按由小到大排序
2.统计/etc/passwd中每种shell的被使用次数
3.用fdisk -l命令只显示出分区和文件系统的类型
4.统计/etc/passwd文件中sbin这个单词出现多少次
5.用find命令查找/根目录下所有包含特殊权限的对象,并只显示出对象的权限和文件名称,不能显示错误提示
6.列出前5位占MEM最多的进程的命令
7.只显示网卡eth0的IP地址
答案:
(1)find /boot –exec ls -l {} \; | tr -s ' ' | cut -d' ' -f5 | grep -v ^$ | sort –n
(2)cat /etc/passwd | cut -d: -f7 | sort | tail -n +2 | uniq -c
(3)fdisk -l | grep ^/dev | tr -s '*' ' ' | cut -d' ' -f1,6-
(4)cat /etc/passwd | tr -s ':/ ' '\n' | sort | uniq -c | grep sbin
(5)find / -perm +7000 -exec ls -ld {} \; 2>/dev/null |tr -s ' ' | cut -d' ' -f1,9 | cut -c 2-10,12-
(6)ps aux | tr -s ' ' | tail -n +2 | sort -k4 -rn | head -5
(7)ifconfig eth0 | grep "inet addr" | tr -s ':' ' ' |cut -d' ' -f4
练习:每2秒钟输出一次系统时间。
解析:不停输出–》死循环while–》sleep 2–》时间格式:年月日时分秒
答案:
#!/bin/bash
while :
do
echo $(date +%F' '%H:%M:%S) >>/lianxi/timeout.txt
sleep 2
done
[或者:date +'%Y-%m-%d %H:%M:%S']
结果:
判断IP是否合法
编写判断IP地址是否合法的脚本
①提醒用户输入ip地址②要求判断文件中的ip地址是否是合法的ipv4地址③不合法的ip地址给与提醒④输出用户输入的ip地址
分析:首先有三个点,其次,第一部分为1-223,其他为0-255即可。
答案:
#!/bin/bash
while :
do
clear
read -p "Please input the IP:" addr
echo "$addr" >iphefa.txt
if ( (cat "iphefa.txt"|egrep "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$")&>/dev/null )
then
echo "The IP that you input is :$addr"
break
else
echo "Please input the right IP!!"
read -p "Please input anykey to continue......"
fi
done
判断用户是否存在,存在则设置密码,不存在就新建,然后给用户设置密码
练习1:设置密码
判断用户是否存在,存在则设置密码,不存在就新建,然后给用户设置密码,用户输入的密码长度小于6位时给与提醒,弱密码,如果大于6位,提醒用户设置的密码长度,并且提示安全。
答案:
#!/bin/bash
read -p "Please input the user:" u_name
if id $u_name
then
read -p "Please input the password:" pass
len=$(echo $pass|wc -m)
echo $pass|passwd $u_name --stdin &>/dev/null
else
echo "The user $u_name is isn't exit!"
useradd $u_name &>/dev/null&& echo "User u_name create OK!"
read -p "Please input the password:" pass
echo $pass|passwd $u_name --stdin &>/dev/null
fi
[[ $pass==?????? ]] && echo "password is ok!And the lens is $(( $len-1 )),it's good!"||echo "password is so short!"
怎么得到密码的长度
(1)
#a=123
#len=echo ${#a} –》非常准确!
echo ${#a} $a中字符串的个数
echo ${a:3} $a中从第三个开始取直到结束
echo ${a:3:2} $a中从第三个开始去两个字符
echo ${a: -1} 取最后一个字符
echo ${a#*.} 从左边开始删除直到遇到.为止
echo ${a##*.} 从左边开始删除直到遇到最后一个.为止
echo ${a%.*} 从右面开始删除直到遇到.为止
echo ${a%%.*} 从右面开始删除直到遇到最后一个.为止
echo ${a/abc/111} 将变量a中的第一个abc替换成111
echo ${a//abc/xyz} 将变量a中的所有的abc替换成xyz
(2)len=echo $a|wc -m –》得到的值比实际大1
批量添加用户while,for.note
for循环批量添加
批量添加用户并且满足以下要求:
答案:
#!/bin/bash
read -p "请输入用户名的前缀:" a
read -p "请输入用户的数目:" num
if (( $num<=10 ))
then
n=0
for i in `seq $num`
do
if useradd $a$i &>/dev/null
then
echo "用户$a$i创建成功!"
(( n++ ))
echo "123456"|passwd $a$i --stdin &>/dev/null
fi
done
echo "一共创建的用户数:$n个"
else
echo "最多只能创建10个用户啦!"
fi
用while循环批量添加20个用户
要求:
①用户名称以stu开头,按数字顺序进行编号
②一共添加20个用户,即stu1、stu2……
③初始密码均设置为123456
答案:
#!/bin/bash
a="stu"
i=1
while (( i<=20 ))
do
useradd $a$i
echo "123456"|passwd --stdin $a$i &>/dev/null
(( i++ ))
done
假如用户名在一个文件里,怎么解决
#!/bin/bash
cat username.txt|while read name pass --》name pass 叫啥都行
do
id $name &>/dev/null||useradd $name
echo "$pass"|passwd $name --stdin &>/dev/null
done
(||:或符号,id命令执行不成功,才执行后面的命令)
使用条件测试
练习:使用条件测试完成下列任务
(1)测试/分区磁盘空间,小于10%,显示“一切正常”,否则显示“当前的磁盘空间是 磁盘空间% 警告”
(2)统计当前系统的登陆用户,登陆用户小于3个,显示“一切正常”,否则显示“登陆用户已经有:个数”
(3)测试当前主机eth0的网卡入站和出站流量,只要两个都大于200MiB,就显示“警告”;
(4)当内存空闲空间小于内存的5%时,显示“内存不足”,否则显示“当前空闲内存是:内存空闲数值”
答案:
(1)#df -Th
#!/bin/bash
a=$(df -Th|grep sda3|tr -s ' '|awk '{print $6}'|tr -d %) --》tr -d 删除%
if (( $a<10 ))
then
echo "Everything is OK!"
else
echo "Now is:$a % free space!"
fi
(2)#who
#!/bin/bash
a=$(who|wc -l)
(($a<3))&&echo "Everything is OK!"||echo "The user is: $a "
(3)#watch -n 1 "/sbin/ifconfig eth0“
watch -n 1 "/sbin/ifconfig eth0|grep bytes|tr -s ' '|cut -d ' ' -f8|tr -d '(' ")
(4)#free
#!/bin/bash
free=$(free|grep "Mem"|tr -s ' '|awk -F ' ' '{print $4}')
tocal=$(free|grep "Mem"|tr -s ' '|awk -F ' ' '{print $2}')
echo "The free space is: $free"
echo "The tocal space is:$tocal"
bai=$(echo -n 0;echo "scale=2;$free/$tocal"|bc)
--》echo -n 0,下一条命令不换行
bai_xin=$(echo $bai|tr -d '0.')
echo "$bai_xin"
(($bai_xin<5))&&echo "The mem isn't enough!!"||echo "当前空闲内存是:$free,空闲百分比:$bai_xin%"
执行效果:
双色球的选择(数组和seq的应用)
数组和seq命令的应用
选择双色球
答案:
#!/bin/bash
echo "欢迎购买福彩双色球,按任意键机选一注"
redball=($(seq 32))
echo -e "\033[31m红球:\n$(echo ${redball[@]})\033[0m" --》显示数组元素
blueball=($(seq 16))
echo -e "\033[34m蓝球:\n$(echo ${blueball[@]})\033[0m"
blen=${#blueball[@]} --》blen存的是篮球的总数
for i in $(seq 6) --》随机取6个红球
do
rlen=${#redball[@]} --》rlen存的是红球总数
rnum=$((RANDOM % rlen))
rb[x++]=${redball[rnum]} -》rb数组存的是选出来的6个红球
unset redball[rnum] -》从原红球数组删除已选的
redball=(${redball[@]})
done
bnum=$((RANDOM % blen))
bb=${blueball[bnum]}
read -n1 -s --》暂停功能,实现按任意键选择的功能。
echo -e "你的幸运号码是:******** \033[31m红球:${rb[@]}\033[0m \033[34m蓝球:$bb\033
[0m ********"
统计某个文件夹下有多少个文件夹
答案:
find 文件夹 -maxdepth 1 -type d|tail -n +2|wc -l
运行结果:
目录的深度从0开始算 ,0代表目录本身,1 代表当前目录下的文件夹 2代表当前目录下的文件夹里的子文件夹 ,以此类推。
统计某文件夹下,某种文件后缀名的文件的数目
答案:
#!/bin/bash
read -p "please input the dir:" DIR
for i in "$@" --》$@ 所有的位置变量
do
num=$(find $DIR -type f -name "*$i"|wc -l)
echo "yi $i jiewei de wen jian shu mu shi:" $num
done
执行结果:
统计日志里访问次数最多的10个ip地址
练习:
将access.log 文件里的web日志访问次数最多的10个ip地址,显示出来要求格式如下:
1 172.16.30.123 tocal:1898
2 172.16.30.34 tocal:1800
3 172.16.20.13 tocal:1456
答案:
#cat access.log | cut -d " " -f1 | sort | uniq -c | sort -k1 -nr | head | tr -s “ “| cat -n | awk -F “ ” ‘{print $1,$3,“tocal:”$2}’
分析:
截取文件里的ip–》相同ip在一起–》去重统计–》按第一列的数值大小降序–》取前十个–》压缩空格–》产生行号–》截取1,3,2列
效果:
简单版:
构造的文件内容如下:
命令:
#cat access.log|sort|uniq -c|sort -k1 -nr|awk '{print $2"tocal:"$1}'|cat -n
结果:
dd
无意义,while dd:每次产生1个1M大小的文件来消耗内存
每次产生1个1M大小的文件来消耗内存的例子:
#cat while4.sh
i=1
while true
do
echo “$i”
((i++))
(dd if=/dev/zero of=dd.dd$i bs=1M count=1)&
done
–》每次产生1个1M大小的文件,并且放到后台去运行。
选择菜单的应用
编写脚本显示如下图所示效果,要求选择一个菜单后,显示出来选择的是什么。
答:
#!/bin/bash
echo -e "\e[31m\t\t***系统管理工具***\e[0m"
echo -e "\n"
echo -e "\t1.\t显示磁盘接口信息"
echo -e "\t2.\t显示网络接口信息"
echo -e "\t3.\t显示内存空间信息"
echo -e "\t4.\t退出菜单"
echo -e "\n"
read -p "请输入选项:" choise
echo "你的选择是:$choise"
芝麻开门 [[字符串比较]]
例:字符串的比较
芝麻开门:直到说出芝麻开门才停,否则一直说“山无棱,天地合,才敢与君绝。”
答案:
#!/bin/bash
until false
do
read -p "山无棱,天地合,才敢与君绝:" PIN
if [[ $PIN == "open door" ]]
then
echo "your answer is OK!"
break
fi
done
执行结果:
最经典的ping,检查能用
练习:
检查整个局域网中172.16.30.0/16,172.16.30.1到30.254之间的ip,有哪些ip正在使用,哪些没有使用;显示出正在使用的ip地址和总数
答案:
#!/bin/bash
for a in `seq 1 5`
do
ip=192.168.227.$a
echo $ip
(ping $ip -c 1 -i 0.2 -w 1 &>/dev/null)
if (( $?==0 ))
then
echo "$ip is UP">>IPADDR.txt
else
echo "$ip is DOWN">>IPADDR.txt
fi
done
sleep 3
num_up=`cat IPADDR.txt|grep UP|wc -l`
num_down=`cat IPADDR.txt|grep DOWN|wc -l`
echo "There are $num_up computers UP."
echo "There are $num_down computers DOWN."
执行结果: