shell脚本练习
这篇文章主要介绍shell编程的实例 一、逻辑判断之if语句1.判断年龄?[[email?protected] 9_1 ]#cat iftest.sh #!/bin/bash read -p "Please input your age:" age ## 判断用户输入的必须是数字 if [[ "$age" =~ ^[0-9]+$ ]];then true else echo "Please input digit" exit 10 fi ## 判断用户的年龄,并输出相应的信息 if [ "$age" -ge 0 -a $age -le 18 ];then echo "good good study,day day up" elif [ "$age" -gt 18 -a $age -le 60 ];then ## 由于前面已经判断为数字,并且为正整数,所以的 "$age" -gt 18 可以省略; echo "work hard" elif [ "$age" -gt 60 -a $age -le 120 ];then ## 同理,这里的"$age" -gt 60也可以省略,优化 echo "enjoy your life" else echo "you don not come from the earch" fi 2.如何判断yes或no?
#!/bin/bash read -p "Input yes or no:" answer ans=`echo "$answer"|tr ‘A-Z‘ ‘a-z‘` if [ "$ans" = "yes" -o "$ans" = "y" ];then echo "YES" elif [ "$ans" = "no" -o "$ans" = "n" ];then echo "NO" else echo "Please input yes or no" fi
#!/bin/bash read -p "Input yes or no:" answer if [[ "$answer" =~ ^[Yy]([Ee][Ss])?$ ]];then echo YES elif [[ "$answer" =~ ^[Nn][Oo]?$ ]];then echo "NO" else echo "Please input yes or no" fi 4.判断是否富有或帅气?[[email?protected] 9_1 ]#vim yesorno2.sh #!/bin/bash read -p "Are you rich? yes or no: " answer if [[ "$answer" =~ ^[Yy]([Ee][Ss])?$ ]];then echo OK elif [[ "$answer" =~ ^[Nn][Oo]?$ ]];then read -p "Are you handsome? yes or no: " answer if [[ "$answer" =~ ^[Yy]([Ee][Ss])?$ ]];then echo Ok exit elif [[ "$answer" =~ ^[Nn][Oo]?$ ]];then echo "work hard" else echo "Please input yes or no" fi else echo "Please input yes or no" fi 二、逻辑判断之case语句1.判断数字[[email?protected] 9_1 ]#vim casetest.sh #!/bin/bash read -p "Please input a digit: " num case $num in 1|2|3) echo 1,2,3 ;; 4|5|6) echo 4,5,6 ;; 7|8|9) echo 7,8,9 ;; *) echo other digit ;; esac 2.判断yes|no#!/bin/bash read -p "Please input yes or no: " ans case $ans in [Yy]|[Yy][Ee][Ss]) echo YES ;; [Nn]|[Nn][Oo]) echo NO ;; *) echo input false ;; esac 3.打印菜单:[[email?protected] ~ ]#cat menu.sh #!/bin/bash cat <<EOF 1:lamian 2:huimian 3:daoxiaomian 4:junbing 5:mifan EOF read -p "Please choose the number: " num case $num in 1) echo "lamian price is 15" ;; 2) echo "huimian price is 18" ;; 3) echo "daoxiaomian price is 13" ;; 4) echo "junbing price is 10" ;; 5) echo "mifan price is 2" ;; *) echo "INPUT false" esac 效果: [[email?protected] ~ ]#sh menu.sh 1:lamian 2:huimian 3:daoxiaomian 4:junbing 5:mifan Please choose the number: 5 mifan price is 2 三、循环之for循环
[[email?protected] 9_2 ]#for num in 1 2 3 4 5;do echo "num=$num"; done num=1 num=2 num=3 num=4 num=5 1.不断追加求和[[email?protected] 9_2 ]#sum=0; for num in 1 2 3 4 5; do sum=$[sum+num];done ;echo sum=$sum sum=15 2.求1+2+3+..+100的和 (面试题)方法1: {1..100}生成序列 [[email?protected] 9_2 ]#sum=0; for num in {1..100}; do sum=$[sum+num];done ;echo sum=$sum sum=5050 ## 用于计算的方式有$[] 和$(())以及let等等。 方法2:seq 100生成序列 [[email?protected] 9_2 ]#sum=0; for num in `seq 100`; do sum=$[sum+num];done ;echo sum=$sum sum=5050 2.1 求1+2+3+..+100以内所有奇数的和|所有偶数的和?奇数之和: [[email?protected] ~ ]#sum=0; for num in {1..100..2}; do sum=$[sum+num];done ;echo sum=$sum sum=2500 [[email?protected] ~ ]#sum=0; for num in `seq 1 2 100`; do sum=$[sum+num];done ;echo sum=$sum sum=2500 偶数之和: [[email?protected] ~ ]#sum=0; for num in {2..100..2}; do sum=$[sum+num];done ;echo sum=$sum sum=2550 [[email?protected] ~ ]#sum=0; for num in `seq 2 2 100`; do sum=$[sum+num];done ;echo sum=$sum sum=2550 2.2 打印奇数和偶数的几种方法?[[email?protected] 9_2 ]#seq 1 2 10————打印奇数 1 3 5 7 9 [[email?protected] 9_2 ]#seq 2 2 10————打印偶数 2 4 6 8 10 [[email?protected] 9_2 ]#seq 1 10 |sed -n "1~2p" ——————sed打印奇数 1 3 5 7 9 [[email?protected] 9_2 ]#seq 1 10 |sed -n "2~2p"————————sed打印偶数 2 4 6 8 10 [[email?protected] ~ ]#echo {1..10..2} ————————————————{}也可以实现输出奇数 1 3 5 7 9 [[email?protected] ~ ]#echo {2..10..2} ————————————————{}打印偶数 2 4 6 8 10 3.练习:如何实现批量执行一个目录下的所有脚本?————(前提:所有文件都拥有x权限,并且是非交互式的)[[email?protected] 9_2 ]#ls case_yesorno.sh test.sh [[email?protected] 9_2 ]# [[email?protected] 9_2 ]#for filename in *.sh;do ./$filename;done Please input yes or no: yes YES hello,world 4.练习:批量创建user1..10的用户,并设置密码为magedu,设置首次登录更改密码?[[email?protected] 9_2 ]#vim createuser_n.sh #!/bin/bash for num in {1..10};do useradd user${num} echo "magedu" |passwd --stdin user${num} &> /dev/null passwd -e user${num} &> /dev/null done 5.练习:编写一个×××扫描器,实现扫描一个网段(1-254)中那些主机是开机的?## 默认是顺序执行,ping完一个ip后再ping下一个,那么可不可以并行执行? [[email?protected] 9_2 ]#cat scanip.sh #!/bin/bash ## 每次执行前清空文件 > /data/iplist.log net=172.20.129 for i in {1..254};do ## 添加{}实现并行执行 { if ping -c1 -W1 $net.$i &> /dev/null ;then echo $net.$i is up echo $net.$i >> /data/iplist.log ## 注意这里是追加,所以在脚本开始清空文件 else echo $net.$i is down fi } & ## 前后对应,并放入后台执行 done wait ## 由于需要手动按enter退出,所以添加wait命令自动退出 优化版:交互式输入 [[email?protected] 9_2 ]#vim scanip.sh #!/bin/bash > /data/iplist.log ## 交互式输入 read -p "Please input the network:(eg:192.168.0.0):" net ## 截取前三段,否则出现1.1.1.0.249情况 net=`echo $net|cut -d. -f1-3` for i in {1..254};do { if ping -c1 -W1 $net.$i &> /dev/null ;then echo $net.$i is up echo $net.$i >> /data/iplist.log else echo $net.$i is down fi } & done wait 6.练习:写一个计算网络ID的netid.sh,ip地址和子网掩码做与运算,如下所示:[[email?protected] 9_2 ]#echo $[193&240] 192 [[email?protected] 9_2 ]#cat netid.sh #!/bin/bash read -p "input a ip: " ip read -p "input a netmask: " netmask ## 每次cut取一个字段,然后循环4次 for i in {1..4};do net=`echo $ip |cut -d. -f$i` mask=`echo $netmask |cut -d. -f$i` if [ $i -eq 1 ];then ## 先一个字段与另外一个字段相与,最后再进行组合 netid=$[net&mask] else netid=$netid.$[net&mask] fi done echo netid=$netid 优化版: [[email?protected] 9_2 ]#cat netid.sh #!/bin/bash read -p "input a ip: " ip read -p "input a netmask: " netmask for i in {1..4};do net=`echo $ip |cut -d. -f$i` mask=`echo $netmask |cut -d. -f$i` subnetid=$[net&mask] if [ $i -eq 1 ];then netid=$subnetid else netid=$netid.$subnetid fi done echo netid=$netid 其他参考: [[email?protected] 9_2 ]#cat netid1.sh #!/bin/bash read -p "input a ip: " ip read -p "input a netmask: " netmask for (( i = 1; i < 5; i++ ));do ip1=`echo $ip |cut -d. -f$i` netmask1=`echo $netmask |cut -d. -f$i` echo -n $[$ip1&$netmask1] ## 用-n实现不换行追加 if [ $i -eq 4 ];then ## 每次输出一个网络id字段后并输出一个点,然后不断追加 echo "" else echo -n "." fi done [[email?protected] 9_2 ]# 7.练习:通过交互式的方式输入行数和列数,打印出矩形?[[email?protected] 9_2 ]#cat rectangle.sh #!/bin/bash read -p "input line number: " x read -p "input colume number: " y for row in `seq $x`;do ## 指定行数打印多行 for col in `seq $y`;do ## 通过指定列数打印一行 echo -e "*c" done echo ## 每一行打印完后换行 done 优化版:添加颜色显示,并闪烁 [[email?protected] 9_2 ]#cat rectangle.sh #!/bin/bash read -p "input line number: " x read -p "input colume number: " y for row in `seq $x`;do ## 指定行数打印多行 for col in `seq $y`;do ## 通过指定列数打印一行 color=$[RANDOM%7+31] ## RANDOM%7表示0-6,+31即31-37 echo -e " 33[1;5;${color}m* 33[0mc" ## 1高亮显示,5闪烁,c换到行尾表示不换行 done echo ## 每一行打印完后换行 done [[email?protected] 9_2 ]# 8.练习:打印等腰三角形利用for的第二种语法实现 [[email?protected] 9_4 ]#cat fortriangle.sh #!/bin/bash read -p "Please input a line number: " line for ((i=1;i<=line;i++));do for ((j=1;j<=$[line-i];j++));do echo -n " " done for ((k=1;k<=$[2*i-1];k++));do echo -n "*" done echo done 9.打印九九乘法表方法1: [[email?protected] 9_4 ]#vim multi.sh #!/bin/bash for i in {1..9};do ## 外层循环决定了打几行,i相当于行号 for j in `seq $i`;do ## j表示其中的一行循环多少遍? echo -e "$j*$i=$(($j*$i))tc" ## 计算$j*$i的结果,并以tab分隔,不换行; done echo ## echo的位置表示打印一行后进行换行; done [[email?protected] 9_4 ]#sh multi.sh 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
方法2:C语言风格 [[email?protected] 9_4 ]#cat for_mult.sh #!/bin/bash for ((i=1;i<=9;i++));do for ((j=1;j<=i;j++));do echo -e "$j*$i=$[j*i]tc" done echo done 10.在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字母,如:1AbCdeFgH.html[[email?protected] 9_4 ]#vim create.sh #!/bin/bash for i in {1..10};do touch $i`tr -dc "0-9a-zA-Z" < /dev/urandom|head -c8` done 四、循环之while循环1.练习:计算1+2+3+..+100的和[[email?protected] 9_4 ]#vim while.sh #!/bin/bash sum=0 i=1 while [ $i -le 100 ];do let sum+=i let i++ done echo sum=$sum "while.sh" [New] 8L,86C written [[email?protected] 9_4 ]#sh while.sh sum=5050 2.练习:九九乘法表9_4 ]#vim whilemult.sh #!/bin/bash i=1 while [ $i -le 9 ];do j=1 while [ $j -le $i ];do echo -e "$j*$i=$[$j*$i]tc" let j++ done echo let i++ done [[email?protected] 9_4 ]#sh whilemult.sh 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9= 3. 练习:打印等腰三角形[email?protected] 9_4 ]#cat while_triangle.sh #!/bin/bash read -p "Please input a line number: " line i=1 ## 打印多行 while [ "$i" -le "$line" ];do ## print space ## 打印空格 j=1 while [ "$j" -le $[line-i] ];do echo -n " " ##或者使用 echo -e " c" let j++ done ## print * ## 打印*的个数 k=1 while [ "$k" -le $[2*i-1] ];do echo -n "*" let k++ done let i++ echo done [[email?protected] 9_4 ]#sh while_triangle.sh Please input a line number: 10 * *** ***** ******* ********* *********** ************* *************** ***************** *******************
4.练习:监控httpd服务的状态?#!/bin/bash SLEEPTIME=10 while : ;do ## :和true都表示为真 if killall -0 httpd &> /dev/null ;then ## kill -0 表示监控进程是否在运行 true else service httpd restart echo "At `date +‘%F %T‘` httpd restart" >> /var/log/checkhttpd.log fi sleep $SLEEPTIME ## 等待时间 done ##建议使用nohup script & 放入后台执行,终端的退出将不影响执行。 5.练习:编写脚本,利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大值和最小值[[email?protected] 9_4 ]#cat formaxmin.sh #!/bin/bash echo -e "random list:c" for ((i=0;i<10;i++));do rand=$RANDOM echo -e " $randc" if [ $i -eq 0 ];then ## 第一次的随机数字没有可比的数字,所以既是最大值又是最小值; max=$rand min=$rand fi if [ $max -lt $rand ];then ## 如果随机数大于最大值,则rand替换为最大值; max=$rand elif [ $min -gt $rand ];then ## 否则为假,即随机数<max,并且<min,则替换为最小值。 min=$rand else true ## 如果是其他情况,则默认 fi done echo echo max is $max echo min is $min 效果如图: [[email?protected] 9_4 ]#sh formaxmin.sh random list: 18428 5303 6933 16210 2577 4107 23750 16836 3435 14399 max is 23750 min is 2577 五、循环之until循环注意:为真,退出 1.练习:查看系统登录用户,如果有hacker这个登录用户,则踢出去?[[email?protected] 9_4 ]#cat untiltest.sh #!/bin/bash until who|grep -q "^hacker&;";do sleep 3 done ## 如果有hacker用户在登录,则退出脚本,并执行下面的pkill语句。 pkill -9 -U hacker ## 注意 pkill -9 可以杀死用户所有的进程。 ## 优化版:不退出脚本,进入死循环,hacker一旦登录,则直接踢出去 [[email?protected] 9_4 ]#cat untiltest.sh #!/bin/bash until false; do ## 为假则进入死循环 who|grep -q "^hacker&;" && pkill -9 -U hacker sleep 3 done 其他小练习1.练习:随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出#!/bin/bash rand=$[RANDOM%11] ## 生成0-10的随机数字 while read -p "input a number: " num;do if [[ ! $num =~ ^[0-9]+$ ]];then ## 由于直接比较,不是> 数字的话会报错,所以进行判断; echo "Please input a digit" continue ## 结束本次循环 elif [ $num -gt $rand ];then echo $num is greater elif [ $num -lt $rand ];then echo $num is little else echo "guess OK" break ## 退出整个循环 fi done 2.练习:逐行读取df的信息,然后判断分区的利用率是否大于8,大于则进行提示方法1: [[email?protected] 9_4 ]#cat diskcheck.sh #!/bin/bash df |sed -n "/sd/p"|while read line;do name=`echo $line |tr -s " " %|cut -d% -f1` ## 通过echo $line对读取到的每一行进行处理 used=`echo $line |tr -s " " %|cut -d% -f5` if [ $used -gt 8 ];then echo "$name will be full;$used %" fi done [[email?protected] 9_4 ]#sh diskcheck.sh /dev/sda2 will be full;9 % /dev/sda1 will be full;16 % 方法2: #!/bin/bash df |while read line;do if [[ "$line" =~ /dev/sd.* ]];then used=`echo $line|tr -s " " %|cut -d% -f5` if [ $used -gt 8 ];then echo "$line" |tr -s " " :|cut -d: -f1,5 fi fi done [[email?protected] 9_4 ]#sh diskcheck1.sh /dev/sda2:9% /dev/sda1:16% 3.练习:扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为62985600,并提示该用户的GECOS信息修改成功?[[email?protected] 9_4 ]#cat user.sh #!/bin/bash while read line ;do GECOS=`echo $line|cut -d: -f5` USER=`echo $line|cut -d: -f1` [ -z "$GECOS" ] && chfn -f $USER -p 2985600 $USER &> /dev/null; done < /etc/passwd 4.练习: ss -nt查看访问连接的ip,如果达到两个,就设置防火墙策略拒绝连接。[[email?protected] 9_4 ]#vim test.sh #!/bin/bash ss -nt|sed -nr ‘/ESTAB/s/.* (.*):.*/1/p‘|sort|uniq -c|while read line;do ## 取出ip并统计次数,然后逐行读取; IP=`echo $line|cut -d" " -f2` num=`echo $line|cut -d" " -f1` if [ "$num" -ge 2 ];then iptables -A INPUT -s $IP -j REJECT ## 如果连接数>2,则使用防火墙策略阻止连接 else true fi done 5.select菜单
[[email?protected] ~ ]#cat select.sh #!/bin/bash PS3="please choose a digit: " ## PS3专门用来提供输入 select MENU in jiaozi lamian mifan daoxiaomian quit;do ## in后面的参数默认按照序号1 2 3 4等一一对应; case $MENU in jiaozi) echo "Your choose is $REPLY" ## 变量REPLY专门用于存储用户输入的结果 echo "$MENU price is 20" ;; lamian) echo "Your choose is $REPLY" echo "$MENU price is 15" ;; mifan) echo "Your choose is $REPLY" echo "$MENU price is 18" ;; daoxiaomian) echo "Your choose is $REPLY" echo "$MENU price is 12" ;; quit) echo "Your choose is $REPLY" break ;; *) echo "Your choose is $REPLY" echo "choose again" ;; esac done 效果: [[email?protected] ~ ]#sh select.sh 1) jiaozi 2) lamian 3) mifan 4) daoxiaomian 5) quit please choose a digit: 1 Your choose is 1 jiaozi price is 20 please choose a digit: 2 Your choose is 2 lamian price is 15 please choose a digit: 5 Your choose is 5 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- angularjs – Angular Material:md-datepicker CSS显示问题
- JaxWsProxyFactoryBean 与 JaxWsDynamicClientFactory
- bash – 如何grep,排除一些模式?
- scala中的.pop()等价物
- SpreadJS 在 Angular2 中支持绑定哪些属性?
- forms – Angular2 ControlGroup valueChanges初始绑定
- scala – 推广“下一个排列”函数
- 还见 webservice !
- Basic Tutorials of Redis(9) -First Edition RedisHelper
- angularjs – 如何简化表单验证?