shell脚本积累

来源:互联网 发布:淘宝全国销量排行榜 编辑:程序博客网 时间:2024/06/05 06:27

编者注: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/bashfor i in $(arp | tail -n +2|tr -s ' ' |cut -d' ' -f1)do    arp -d $idone

练习2:产生3个随机数:
方法1:

#for i in {0..9};do echo $RANDOM;done

这里写图片描述

方法2:

#for i in $(seq 10);do echo $RANDOM;done

这里写图片描述

练习3:倒数五秒:

#!/bin/bashfor i in $(seq 5 -1 1)do      echo -en "$i\n";      sleep 1doneecho -e "\e[31m开始!\e[0m"

这里写图片描述

练习4:批量添加用户:

#!/bin/bashULIST=$(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 /rootdbus 81 /rpc 32 /var/cache/rpcbindrpcuser 29 /var/lib/nfshaldaemon 68 /postfix 89 /var/spool/postfixmysql 27 /var/lib/mysql@@@@@@@@@@@@@@

例1:只有模式时,相当于grep

# cat passwd|awk '/liu/'liu1:x:508:508::/home/liu1:/bin/bashliu2:x:509:509::/home/liu2:/bin/bash

例2:只有动作时,就直接执行动作。

# who|awk '{print $2}'tty1pts/0# whoroot     tty1         2016-06-24 23:20root     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/bashstua6 501 /home/stua6 /bin/bashstuv1 502 /home/stuv1 /bin/bashstuv2 503 /home/stuv2 /bin/bash

练习1:查找出用户名里包含liu的用户,输出用户名和uid及shell。

# cat passwd|awk -F':'   '$1  ~/liu/{print $1,$3,$6}'liu1 508 /home/liu1liu2 509 /home/liu2liu3 510 /home/liu3liu4 511 /home/liu4liu5 512 /home/liu5liu 539 /home/liu

练习2:查找出/etc/passwd文件里用户名包含liu并且使用bash的用户。

# cat passwd|awk -F':'  '$1 ~/liu/&&$7 ~/bash/{print $1,$7}'liu1 /bin/bashliu2 /bin/bashliu3 /bin/bashliu4 /bin/bashliu5 /bin/bashliu /bin/bash

例题:

# awk 'BEGIN{print "line one\nline two\nline three"}'line oneline twoline three# awk 'END{print "line one\nline two\nline three"}'line one按Ctrl+D才显示最后三行。line oneline twoline 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行(带行号,带内容)

#awkNR==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.147127.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/bashawk -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/passwd3 rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin4 rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin7 mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash

system函数

# cat listxixi 123haha 456hehe 789
# awk '{system("useradd   "$1)}' list # ls /homehaha  hehe  hello  xixi# awk '{system("userdel -r   "$1)}' list  【命令用双括号括起,后面有空格】# ls /homehello

练习:利用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/bashwarn=10ip=(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   fidone

练习3:检查/var/log/secure日志文件,如果有主机用root用户连接服务器的ssh服务失败次数超过10次(10次必须使用变量),就将这个IP地址加入/etc/hosts.deny文件拒绝其访问,如果这个IP已经存在就无需重复添加到/etc/hosts.deny文件(要求使用awk语句进行字符过滤、大小判断和变量赋值,禁止使用echo、sed、grep、cut、tr命令)

#/bin/bashawk '/Failed password for root/{print $(NF-3)}' /var/log/secure|sort -nr| uniq -c > test        --》sort 按降序排序,uniq -c统计次数NUM=10IP=$(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   fidone

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.txtawk '{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/bashread -p "Please input the username:" u_namecat /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/bashread -p "Please input the ip:" IPread -p "Please input the netmask:" MASKread -p "Please input the dns server:" DNSread -p "Please input the gateway:" GATEWAYa=$(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/bashcat 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/bashmenu(){    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/bashread -p "Please input the sorce:" soif (( $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/bashread -p "Please input the name:" nameread -p "Please input the number:" numread -p "Please input the password:" passfor i in `seq $num`do    id $name$i &>/dev/null|useradd $name$i    echo "$pass"|passwd $name$i --stdin &>/dev/null         done

6
这里写图片描述
答:

#!/bin/bashcat /etc/passwd|awk -F: '$3>500&&$3<5000{print "username:"$1,"uid is "$3,"gid is "$4}'

7
这里写图片描述
答:

#!/bin/bashcat web.log|awk -F '/' '{print $3}'|sort -nr|uniq -c

8
这里写图片描述
答:

#!/bin/bashnames=($(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 1doneecho -e "\n\t\t有请${names[$name1]}演唱《${songs[$song1]}》"#将已经选中的歌和人追加到pass文件里,并且删除用过的数组元素echo "${names[name1]}" >>pass_singers.txtecho "${songs[song1]}" >>pass_songs.txtunset names[name1]unset songs[song1]#重新定义原来的两个数组,并且当数组元素为0时,更新数组;每次选完后更新文件echo "${names[@]}" >singers.txtif ((${#names[@]}==0))then        mv pass_singers.txt singers.txt        echo "Update singers OK!"fiecho "${songs[@]}" >songs.txtif ((${#songs[@]}==0))then        mv pass_songs.txt songs.txt        echo "Update songs OK!"fi

9
这里写图片描述
答:

#!/bin/bashmenu(){        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/bashmenu(){        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 /yummount /dev/cdrom /yum &>/dev/nullcd /etc/yum.repos.dcat >local.repo<<EOF[local_yum]name=local yumbaseurl=file:///yumenabled=1gpgcheck=0EOFyum clean &>/dev/nullecho "yum created successful!!!"#安装mysql服务和启动mysqlyum install mysqld -yservice mysqld start#追加命令到样板文件即可echo "service mysqld start" >>/etc/skel/.bashrc

12
这里写图片描述
答:

#!/bin/bashps aux >aux.txtecho "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/basha=$(netstat -anplt|tr -s ' '|awk -F "[ :]" '/3306/{print $4}')if ( lsof -i:3306 )then        echo "监听地址:$a"else        service mysqld startfi

system tools(菜单 main)

***************system tools*************1.build local yum2.build ftp server3.user management4.memory statistic5.cpu statistic6.disk statistic7.ftp server monitor8.exit******************************************

答案:

#!/bin/bashmenu(){        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/bashtime=0a=$((RANDOM%100))    --》产生099的自然数。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 低了!!"        fidoneif ((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/bashuid=(`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]}"        fidone

方法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/nullcd /etc/yum.repos.dcat >local.repo <<EOF[local_yum]name=local yumbaseurl=file:///yumenabled=1gpgcheck=0EOFyum clean &>/dev/nullecho "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/bashifconfig|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.txtn=0for 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"        fidoneroute -n|tail -n 1  >GATEWAY.txtcat GATEWAY.txt|while read a IP c d e f g ETHdo        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"        fidone

当前主机中哪些是普通用户,哪些是系统用户.note
分析当前主机中所有用户,哪些是普通用户,哪些是系统用户。
分析:
看 passwd文件的UID,uid>500则为普通用户,uid<500则为系统用户,
uid怎么从passwd文件里弄出来,uid>500的用户怎么弄出来,怎么嵌套进循环里。
答案:

#!/bin/bashcat /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."                fidone(闪烁功能:#echo -e"\e[5;33mHello,Word\e[0m"而且是显示黄色,并且闪烁)

点歌程序脚本

点歌程序:v2
1.准备歌手名单,曲库;
2.随机抽歌手,随机抽歌,输出谁要唱什么歌;
3.抽过的歌手,已经唱过的歌手和歌曲都不能再出现。
答案:

#!/bin/bashsongs=($(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 1doneecho -e "\n\t\t有请 ${names[$name1]} 演唱 <<${songs[$song1]}>>"#将已经选中的追加到pass文件里,并且删除用过的数组元素echo "${names[name1]}" >>pass_singer.txtecho "${songs[song1]}" >>pass_songs.txtunset names[name1]unset songs[song1]#重新定义原来的两个数组,并且当数组元素为0时,更新数组echo "${names[@]}" >singer.txtif ((${#names[@]}==0))then        mv pass_singer.txt singer.txt        echo "Update singer is OK!"fiecho "${songs[@]}" >songs.txtif ((${#songs[@]}==0))then        mv pass_songs.txt songs.txt        echo "Update songs is OK!"fi

效果:
这里写图片描述


给登录到当前主机的所有非root用户终端发送一句话

给登录到当前主机的所有非root用户终端发送一句话:“用户名:Hi,I’m Root!”
答案:

#!/bin/bashw|tail -n +3|while read user TTY other  --》w命令显示连接到本机的所有用户do        if [[ "$user" != "root" ]]        then                echo "Hello $user,I am Root!" >/dev/$TTY        fidone

执行结果:
另起一个终端,
这里写图片描述


函数 菜单 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/bashmonitor_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_memmonitor_cpumonitor_diskmonitor_cpu5monitor_mem5

监控脚本的菜单和main函数的实现

#!/bin/bashmenu(){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(){clearecho -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 "请输入你想监控的网址" ipwhile :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;        fidonen=0 ######监控but_q=nullwhile :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 1done}###################备份主函数bakmain(){clearwhile :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        cleardone}#############主函数main(){clearwhile :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"                ;;        esacdone}###############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 "请输入你想监控的网址" ipwhile :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;        fidonen=0 ######监控but_q=nullwhile :do        a=`date +%F`
#!/bin/bash################主菜单menu(){clearecho -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 "请输入你想监控的网址" ipwhile :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;        fidonen=0 ######监控but_q=nullwhile :do        a=`date +%F`        else                >ip.txt                break;        fidonen=0 ######监控but_q=nullwhile :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 1done}###################备份主函数bakmain(){clearwhile :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        cleardone}#############主函数main(){clearwhile :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"                ;;        esacdone}###############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/basha=$(uname -r|awk -F'.' '{print $1"."$2}')if [[ $a>2.6 ]]then        echo "内核版本:$a"else        echo "内核版本太低,无法继续!"fi2.#/bin/basha=$(netstat -anplt|awk '/3306/{print $5}')if ( lsof -i:3306 )then        echo "监听地址:$a"else        service mysqld startfi

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 -c3)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 -57)ifconfig eth0 | grep "inet addr" | tr -s ':' ' ' |cut -d' ' -f4

练习:每2秒钟输出一次系统时间。
解析:不停输出–》死循环while–》sleep 2–》时间格式:年月日时分秒
答案:

#!/bin/bashwhile :do        echo $(date +%F'  '%H:%M:%S) >>/lianxi/timeout.txt        sleep 2done[或者:date +'%Y-%m-%d  %H:%M:%S']

结果:
这里写图片描述


判断IP是否合法

编写判断IP地址是否合法的脚本
①提醒用户输入ip地址②要求判断文件中的ip地址是否是合法的ipv4地址③不合法的ip地址给与提醒④输出用户输入的ip地址
分析:首先有三个点,其次,第一部分为1-223,其他为0-255即可。
答案:

#!/bin/bashwhile :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......"        fidone

判断用户是否存在,存在则设置密码,不存在就新建,然后给用户设置密码
练习1:设置密码
判断用户是否存在,存在则设置密码,不存在就新建,然后给用户设置密码,用户输入的密码长度小于6位时给与提醒,弱密码,如果大于6位,提醒用户设置的密码长度,并且提示安全。

答案:

#!/bin/bashread -p "Please input the user:" u_nameif id $u_namethen        read -p "Please input the password:" pass        len=$(echo $pass|wc -m)        echo $pass|passwd $u_name --stdin &>/dev/nullelse        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/nullfi[[ $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/bashread -p "请输入用户名的前缀:" a read -p "请输入用户的数目:" numif (( $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/basha="stu"i=1while (( i<=20 ))do         useradd $a$i         echo "123456"|passwd --stdin $a$i &>/dev/null         (( i++ ))done

假如用户名在一个文件里,怎么解决

#!/bin/bashcat username.txt|while read name pass  --》name pass 叫啥都行do        id $name &>/dev/null||useradd $name        echo "$pass"|passwd $name --stdin &>/dev/nulldone(||:或符号,id命令执行不成功,才执行后面的命令)

使用条件测试

练习:使用条件测试完成下列任务
(1)测试/分区磁盘空间,小于10%,显示“一切正常”,否则显示“当前的磁盘空间是 磁盘空间% 警告”
(2)统计当前系统的登陆用户,登陆用户小于3个,显示“一切正常”,否则显示“登陆用户已经有:个数”
(3)测试当前主机eth0的网卡入站和出站流量,只要两个都大于200MiB,就显示“警告”;
(4)当内存空闲空间小于内存的5%时,显示“内存不足”,否则显示“当前空闲内存是:内存空闲数值”
答案:

1#df -Th#!/bin/basha=$(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!"fi2#who#!/bin/basha=$(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/bashfree=$(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/bashecho "欢迎购买福彩双色球,按任意键机选一注"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[@]})donebnum=$((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/bashread -p "please input the dir:" DIRfor i in "$@"        --》$@ 所有的位置变量do        num=$(find $DIR -type f -name "*$i"|wc -l)        echo "yi $i jiewei de wen jian shu mu shi:" $numdone

执行结果:
这里写图片描述

统计日志里访问次数最多的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.shi=1while truedo    echo “$i”    ((i++))  (dd   if=/dev/zero    of=dd.dd$i    bs=1M   count=1)&done

–》每次产生1个1M大小的文件,并且放到后台去运行。
这里写图片描述


选择菜单的应用

编写脚本显示如下图所示效果,要求选择一个菜单后,显示出来选择的是什么。
这里写图片描述

答:

#!/bin/bashecho -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 "请输入选项:" choiseecho "你的选择是:$choise"

芝麻开门 [[字符串比较]]

例:字符串的比较
芝麻开门:直到说出芝麻开门才停,否则一直说“山无棱,天地合,才敢与君绝。”

答案:

#!/bin/bashuntil falsedo        read -p "山无棱,天地合,才敢与君绝:" PIN        if [[ $PIN == "open door" ]]        then                echo "your answer is OK!"                break        fidone

执行结果:
这里写图片描述


最经典的ping,检查能用

练习:
检查整个局域网中172.16.30.0/16,172.16.30.1到30.254之间的ip,有哪些ip正在使用,哪些没有使用;显示出正在使用的ip地址和总数

答案:

#!/bin/bashfor 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        fidonesleep 3num_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."

执行结果:
这里写图片描述

原创粉丝点击