博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
shell脚本练习
阅读量:6146 次
发布时间:2019-06-21

本文共 15261 字,大约阅读时间需要 50 分钟。

这篇文章主要介绍shell编程的实例

一、逻辑判断之if语句

1.判断年龄?

[root@centos7 9_1 ]#cat  iftest.sh #!/bin/bashread -p "Please input  your age:" age     ## 判断用户输入的必须是数字if [[ "$age" =~ ^[0-9]+$ ]];then    trueelse    echo "Please input digit"    exit 10fi## 判断用户的年龄,并输出相应的信息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?

思路1:

1.用户输入的所有选择:y|yes|Y|YES,同n|no|N|NO
2.统一判断为大写或者小写:tr进行转换
3.使用两种选择判断:2:使用正则匹配y|yes;n|no或者大写

#!/bin/bashread  -p "Input yes or no:" answerans=`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

思路2:使用正则进行判断

#!/bin/bashread  -p "Input yes or no:" answerif [[ "$answer" =~ ^[Yy]([Ee][Ss])?$ ]];then        echo YESelif [[ "$answer" =~ ^[Nn][Oo]?$ ]];then        echo "NO"else        echo "Please input yes or no"fi

4.判断是否富有或帅气?

[root@centos7 9_1 ]#vim yesorno2.sh#!/bin/bashread -p "Are you rich? yes or no: " answerif [[ "$answer" =~ ^[Yy]([Ee][Ss])?$ ]];then        echo OKelif [[ "$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"        fielse        echo "Please input yes or no"fi

二、逻辑判断之case语句

1.判断数字

[root@centos7 9_1 ]#vim casetest.sh#!/bin/bashread -p "Please input a digit: " numcase $num in1|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/bashread -p "Please input yes or no: " anscase $ans in[Yy]|[Yy][Ee][Ss])    echo YES    ;;[Nn]|[Nn][Oo])    echo NO    ;;*)      echo input false    ;;esac

3.打印菜单:

[root@CentOS6 ~ ]#cat menu.sh #!/bin/bashcat <

三、循环之for循环

help for————两种语法

语法1:
for NAME [in WORDS ... ] ; do COMMANDS; done
语法2:
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done

[root@centos7 9_2 ]#for num in 1 2 3 4 5;do echo "num=$num"; donenum=1num=2num=3num=4num=5

1.不断追加求和

[root@centos7 9_2 ]#sum=0; for num in 1 2 3 4 5; do sum=$[sum+num];done ;echo sum=$sumsum=15

2.求1+2+3+..+100的和 (面试题)

方法1:    {1..100}生成序列[root@centos7 9_2 ]#sum=0; for num in {1..100}; do sum=$[sum+num];done ;echo sum=$sumsum=5050## 用于计算的方式有$[] 和$(())以及let等等。方法2:seq 100生成序列[root@centos7 9_2 ]#sum=0; for num in `seq 100`; do sum=$[sum+num];done ;echo sum=$sumsum=5050

2.1 求1+2+3+..+100以内所有奇数的和|所有偶数的和?

奇数之和:

[root@centos7 ~ ]#sum=0; for num in {1..100..2}; do sum=$[sum+num];done ;echo sum=$sumsum=2500[root@centos7 ~ ]#sum=0; for num in `seq 1 2 100`; do sum=$[sum+num];done ;echo sum=$sumsum=2500

偶数之和:

[root@centos7 ~ ]#sum=0; for num in {2..100..2}; do sum=$[sum+num];done ;echo sum=$sumsum=2550[root@centos7 ~ ]#sum=0; for num in `seq 2  2 100`; do sum=$[sum+num];done ;echo sum=$sumsum=2550

2.2 打印奇数和偶数的几种方法?

[root@centos7 9_2 ]#seq 1 2 10————打印奇数13579[root@centos7 9_2 ]#seq 2 2 10————打印偶数246810[root@centos7 9_2 ]#seq 1 10 |sed -n "1~2p" ——————sed打印奇数13579[root@centos7 9_2 ]#seq 1 10 |sed -n "2~2p"————————sed打印偶数246810[root@centos7 ~ ]#echo {1..10..2}   ————————————————{}也可以实现输出奇数1 3 5 7 9[root@centos7 ~ ]#echo {2..10..2}   ————————————————{}打印偶数2 4 6 8 10

3.练习:如何实现批量执行一个目录下的所有脚本?————(前提:所有文件都拥有x权限,并且是非交互式的)

[root@centos7 9_2 ]#lscase_yesorno.sh  test.sh[root@centos7 9_2 ]#[root@centos7 9_2 ]#for filename in *.sh;do ./$filename;donePlease input yes or no: yesYEShello,world

4.练习:批量创建user1..10的用户,并设置密码为magedu,设置首次登录更改密码?

[root@centos7 9_2 ]#vim createuser_n.sh #!/bin/bashfor num in {1..10};do         useradd user${num}          echo "magedu" |passwd --stdin user${num} &> /dev/null         passwd -e user${num} &> /dev/nulldone

5.练习:编写一个×××扫描器,实现扫描一个网段(1-254)中那些主机是开机的?

## 默认是顺序执行,ping完一个ip后再ping下一个,那么可不可以并行执行?[root@centos7 9_2 ]#cat scanip.sh #!/bin/bash## 每次执行前清空文件> /data/iplist.log                                  net=172.20.129for 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 } &                                          ## 前后对应,并放入后台执行donewait                                                ## 由于需要手动按enter退出,所以添加wait命令自动退出优化版:交互式输入[root@centos7 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 } &donewait

6.练习:写一个计算网络ID的netid.sh,ip地址和子网掩码做与运算,如下所示:

[root@centos7 9_2 ]#echo $[193&240]192[root@centos7 9_2 ]#cat netid.sh #!/bin/bashread -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]    fidoneecho netid=$netid优化版:[root@centos7 9_2 ]#cat netid.sh #!/bin/bashread -p "input a ip: " ipread -p "input a netmask: " netmaskfor 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    fidoneecho netid=$netid其他参考:[root@centos7 9_2 ]#cat netid1.sh #!/bin/bashread -p "input a ip: " ipread -p "input a netmask: " netmaskfor (( 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 "."    fidone[root@centos7 9_2 ]#

7.练习:通过交互式的方式输入行数和列数,打印出矩形?

[root@centos7 9_2 ]#cat rectangle.sh #!/bin/bashread -p "input line number: " xread -p "input colume number: " yfor row in `seq $x`;do                                      ## 指定行数打印多行     for col in `seq $y`;do                                  ## 通过指定列数打印一行        echo -e "*\c"    done    echo                                                    ## 每一行打印完后换行 done优化版:添加颜色显示,并闪烁[root@centos7 9_2 ]#cat rectangle.sh #!/bin/bashread -p "input line number: " xread -p "input colume number: " yfor row in `seq $x`;do                                      ## 指定行数打印多行     for col in `seq $y`;do                                  ## 通过指定列数打印一行        color=$[RANDOM%7+31]                                ## RANDOM%7表示0-6,+31即31-37        echo -e "\033[1;5;${color}m*\033[0m\c"              ## 1高亮显示,5闪烁,\c换到行尾表示不换行    done    echo                                                    ## 每一行打印完后换行 done[root@centos7 9_2 ]#

8.练习:打印等腰三角形

利用for的第二种语法实现[root@centos7 9_4 ]#cat  fortriangle.sh#!/bin/bashread -p "Please input a line number: " linefor ((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:

[root@centos7 9_4 ]#vim multi.sh#!/bin/bashfor i in {1..9};do                                  ## 外层循环决定了打几行,i相当于行号        for j in `seq $i`;do                        ## j表示其中的一行循环多少遍?                echo -e "$j*$i=$(($j*$i))\t\c"      ## 计算$j*$i的结果,并以tab分隔,不换行;        done        echo                                        ## echo的位置表示打印一行后进行换行;done[root@centos7 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语言风格

[root@centos7 9_4 ]#cat for_mult.sh #!/bin/bashfor ((i=1;i<=9;i++));do       for ((j=1;j<=i;j++));do        echo -e "$j*$i=$[j*i]\t\c"    done    echo done

10.在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字母,如:1AbCdeFgH.html

[root@centos7 9_4 ]#vim create.sh #!/bin/bashfor i in {1..10};do        touch $i`tr -dc "0-9a-zA-Z" < /dev/urandom|head -c8`done

四、循环之while循环

1.练习:计算1+2+3+..+100的和

[root@centos7 9_4 ]#vim while.sh#!/bin/bashsum=0i=1while [ $i -le 100 ];do        let sum+=i        let i++doneecho sum=$sum                                                                                                                                                  "while.sh" [New] 8L, 86C written                           [root@centos7 9_4 ]#sh while.sh sum=5050

2.练习:九九乘法表

9_4 ]#vim whilemult.sh#!/bin/bashi=1while [ $i -le 9 ];do        j=1        while [ $j -le $i ];do        echo -e "$j*$i=$[$j*$i]\t\c"        let j++        done        echo         let i++done[root@centos7 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. 练习:打印等腰三角形

ot@centos7 9_4 ]#cat while_triangle.sh #!/bin/bashread -p "Please input a line number: " linei=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[root@centos7 9_4 ]#sh while_triangle.sh Please input a line number: 10         *        ***       *****      *******     *********    ***********   *************  *************** ************************************

思路:先打出空格——————再打印*的个数

定义总行数:line
当前行:i
当前列:j

中间 所在列=总行数line

当前行从开头到中间 的个数=i
space=line-i
当前行 的个数=2i-1

4.练习:监控httpd服务的状态?

#!/bin/bashSLEEPTIME=10while : ;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数字,并显示其中的最大值和最小值

[root@centos7 9_4 ]#cat formaxmin.sh #!/bin/bashecho -e "random list:\c"        for ((i=0;i<10;i++));do    rand=$RANDOM    echo -e " $rand\c"    if [ $i -eq 0 ];then                    ## 第一次的随机数字没有可比的数字,所以既是最大值又是最小值;        max=$rand        min=$rand       fi    if [ $max -lt $rand ];then              ## 如果随机数大于最大值,则rand替换为最大值;        max=$rand    elif [ $min -gt $rand ];then            ## 否则为假,即随机数

五、循环之until循环

注意:为真,退出

为假,则执行循环语句

1.练习:查看系统登录用户,如果有hacker这个登录用户,则踢出去?

[root@centos7 9_4 ]#cat untiltest.sh #!/bin/bashuntil who|grep -q "^hacker\>";do    sleep 3done                                    ## 如果有hacker用户在登录,则退出脚本,并执行下面的pkill语句。pkill -9 -U hacker                      ## 注意 pkill -9 可以杀死用户所有的进程。## 优化版:不退出脚本,进入死循环,hacker一旦登录,则直接踢出去[root@centos7 9_4 ]#cat untiltest.sh #!/bin/bash until false; do                         ## 为假则进入死循环    who|grep -q "^hacker\>" && pkill -9 -U hacker    sleep 3done

其他小练习

1.练习:随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出

#!/bin/bashrand=$[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                       ## 退出整个循环        fidone

2.练习:逐行读取df的信息,然后判断分区的利用率是否大于8,大于则进行提示

方法1:

[root@centos7 9_4 ]#cat diskcheck.sh #!/bin/bashdf |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 %"    fidone[root@centos7 9_4 ]#sh diskcheck.sh/dev/sda2 will be full;9 %/dev/sda1 will be full;16 %

方法2:

#!/bin/bashdf |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    fidone[root@centos7 9_4 ]#sh diskcheck1.sh /dev/sda2:9%/dev/sda1:16%

3.练习:扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为62985600,并提示该用户的GECOS信息修改成功?

[root@centos7 9_4 ]#cat user.sh #!/bin/bashwhile 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,如果达到两个,就设置防火墙策略拒绝连接。

[root@centos7 9_4 ]#vim test.sh #!/bin/bashss -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        fidone

5.select菜单

语法:select: select NAME [in WORDS ... ;] do COMMANDS; done

[root@CentOS6 ~ ]#cat  select.sh #!/bin/bashPS3="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"    ;;    esacdone效果:[root@CentOS6 ~ ]#sh select.sh 1) jiaozi2) lamian3) mifan4) daoxiaomian5) quitplease choose a digit: 1Your choose is 1jiaozi price is 20please choose a digit: 2Your choose is 2lamian price is 15please choose a digit: 5Your choose is 5

转载于:https://blog.51cto.com/13668904/2170418

你可能感兴趣的文章
POJ3694 Network
查看>>
微信小程序开发-框架
查看>>
redo、undo、binlog的区别
查看>>
DropDownList 控制日期控件显示格式
查看>>
RecycleView设置顶部分割线(记录一个坑)
查看>>
【设计模式系列】单例模式的7种写法
查看>>
汉字转拼音 (转)
查看>>
Machine Learning Techniques -6-Support Vector Regression
查看>>
会计基础_001
查看>>
ajax请求拿到多条数据拼接显示在页面中
查看>>
小程序: 查看正在写的页面
查看>>
Jenkins持续集成环境部署
查看>>
检查磁盘利用率并且定期发送告警邮件
查看>>
MWeb 1.4 新功能介绍二:静态博客功能增强
查看>>
摄像机与绕任意轴旋转
查看>>
rsync 服务器配置过程
查看>>
预处理、const与sizeof相关面试题
查看>>
爬虫豆瓣top250项目-开发文档
查看>>
Elasticsearch增删改查
查看>>
oracle归档日志增长过快处理方法
查看>>