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行(带行号,带内容)
#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,
(输出每行的行号,字段数,用户名,最后一个字段,倒数第二个字段)
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)) --》产生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 低了!!" 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 -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/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!"fi(2)#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."
执行结果:
- 常用shell脚本积累
- shell脚本积累
- shell脚本积累---`dirname $0`
- shell脚本积累---shell文件包含
- shell 积累
- shell 积累
- shell积累
- shell知识积累
- shell script 入门积累
- android shell 命令积累
- Shell编程积累
- shell 问题积累
- Linux Shell 学习积累
- 常用shell积累
- 工作命令行积累 shell
- shell sed 积累
- python 脚本编程积累
- python 脚本编程积累
- 初级phper的学习历程
- Recycleview实现购物车
- Kaldi语音识别注意事项
- CNN:卷积神经网络
- jdk7 动态语言功能
- shell脚本积累
- Python字符串操作
- 深度对抗学习在图像分割和超分辨率中的应用
- 斯坦福大学机器学习笔记——机器学习基础以及有监督学习和无监督学习举例说明
- 将光源信息应用到立方体(一)
- 基于JS的类型检测
- golang,使用类型断言的一个例子
- 【51Nod1382】捡石子
- HCE