系统基础之shell脚本编程详解2

shell脚本编程2:

  在上节我们介绍了shell脚本编程,但只是介绍了基础的内容,下面将为大家介绍shell的脚本的高级用法,判断与循环.判断分为两种:if语句和case语句;循环分为三种:for语句,while语句,until语句,select语句


判断语句:


 在脚本的编写中,我们要使用大量的数据和命令,但对于使用的数据,我们要想办法进行验证,,判断数据的正确性,来达到我们编写脚本的目的.于是判断机制尤为重要,来看下两个判断语句.


1.if语句

  特点: 

    选择执行

    判断条件为真,执行后面语句;否则,执行else后的语句

    if可嵌套

  语法:

    单分支:

      if 判断条件: then
          条件为真的分支代码
      fi

     双分支:

       if 判断条件; then
        条件为真的分支代码
       else
        条件为假的分支代码
       fi

    多分支:

      if CONDITION1; then
          if-true
        elif CONDITION2; then
          if-ture
        elif CONDITION3; then
         if-ture
        …
       else
         all-false
       fi

    注意:逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句

  实例:

    根据命令的退出状态来执行命令
    if ping -c1 -W2 station1 &> /dev/null; then
       echo 'Station1 is UP'
    elif grep "station1" ~/maintenance.txt &> /dev/null ;then
      echo 'Station1 is undergoing maintenance‘
    else
      echo 'Station1 is unexpectedly DOWN!'
      exit 1
    fi

2.case语句

  特点:

  1.风格:

    case支持glob风格的通配符:
    *: 任意长度任意字符
    ?: 任意单个字符
    []:指定范围内的任意单个字符
    a|b: a或b

   2.配合死循环使用

  语法:

    case 变量引用 in
    PAT1)
      分支1
      ;;
    PAT2)
      分支2
       ;;
    …
    *)
      默认分支
       ;;
    esac

  实例:

    case $input in     
    [yY][eE][sS]|[yY])
        echo " user enter input is yes"
        ;;
    [Nn][oO]|[nN])
        echo " user enter input is no"
        ;;
    
    [oO][tT]|[oO])
        echo " user enter input is other"
        ;;
    *)
        exit 2
        ;;
    esac


循环语句:


 在编写脚本时,我们会遇到批量的操作,对于行数,数量等有规律的数据,我们可以使用循环的方法,来简化我们的脚本,也会使我们的的思路更加清晰.来认识下四个循环语句.

 循环执行
   将某代码段重复运行多次
   重复运行多少次:
   循环次数事先已知
   循环次数事先未知
   有进入条件和退出条件

  1. for语句

    1. 语法

      for 变量名 in 列表;do
       循环体
      done

    2. 执行机制

      依次将列表中的元素赋值给“变量名” ; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束

    3. 列表生成方式

      (1) 直接给出列表
      (2) 整数列表:
      (a) {start..end}
      (b) $(seq [start [step]] end)
      (3) 返回列表的命令 $(COMMAND)
      (4) 使用glob, 如: *.sh
      (5) 变量引用;$@, $

    4. 特殊用法

      双小括号方法,即((…))格式,也可以用于算术运算
      双小括号方法也可以使bash Shell实现C语言风格的变量操作
       #I=10
       #((I++))

      for循环的特殊格式:
       for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
       do
         循环体
       done
      控制变量初始化:仅在运行到循环代码段时执行一次
      控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

      1. for (i=1;i<=100;i++)
             do  
             echo $i
            done
  2. while语句

    1. 语法

      while CONDITION; do
       循环体
      done

    2. 执行机制

      CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“ true”,则执行一次循环;直到条件测试状态为“ false”终止循环 因此: CONDTION一般应该有循环控制变量;而此变量的值
    会在循环体不断地被修正
     进入条件: CONDITION为true;
     退出条件: CONDITION为false

    c.特殊用法

      while循环的特殊用法(遍历文件的每一行):
     

     while read line; do
      循环体
     done < /PATH/FROM/SOMEFILE
     

     依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
    练习:
     扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为62985600,并提示该用户的GECOS信息修改成功

  3. until语句

    1. 语法

      until CONDITION; do
      循环体
       done

    2. 执行机制

    进入条件: CONDITION 为false
    退出条件: CONDITION 为true

4.select语句

   a.语法

    select variable in list
     do
     循环体命令
    done

   b.执行机制

    select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3 提示符,等待用户输入
    用户输入菜单列表中的某个数字,执行相应的命令
    用户输入被保存在内置变量 REPLY 中。

   c.特殊用法

    select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c退出循环。
    select 经常和 case 联合使用

    与 for 循环类似,可以省略 in list , 此时使用位置参量

在循环中,有些语句,可以实现对循环过程的控制.

  1. continue

     用于循环体中
     continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层
      while CONDTIITON1; do
      CMD1
      …
      if CONDITION2; then
       continue
      fi
     CMDn
     …
     done

  2. break

     用于循环体中
     break [N]:提前结束第N层循环, 最内层为第1层
       while CONDTIITON1; do
        CMD1
        …
       if CONDITION2; then
         break
       fi
       CMDn
        …
      done

  3. 无限循环

    while true; do
     循环体

  done
 

  until false; do
   循环体
  done

实战脚本:

1.

#Description: 扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为62985600,并提示该用户的GECOS信息修改成功
#****************************************************
GECOS=" "
while read line;do
username=`echo $line|cut -d: -f1`
GECOS=`echo  $line| cut -d: -f5`
if [ -z  "$GECOS" ];then
	usermod -c "$username#62985600" $username &>/dev/null
	echo "usermod $username over!!!"
else
   echo "$uaername GECOS is exies~~~"
fi
done < /etc/passwd

2.chmod -rw /tmp/file1,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1文件 是否不可读且不可写

#!/bin/bash

FileName=/tmp/file1
[ ! -e $FileName ] && echo "file $FileName is no exits" && exit 2
#chmod -rw $FileName &>/dev/null
[  -r $FileName -a -w $FileName ] && echo  "the file is  read and write  for one user" || echo  "the file is no read and no write  for one user"

3、写一个脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息

#!/bin/bash
read -p "enter a username:" input
id -u $input &>/dev/null
if [ $?  -eq  0  ] ;then
    echo "user $input UID is exits"
else
 echo "user $input is no exits,will useradd $input"
   useradd $input
   echo "useradd $input in over!!!"
   echo "user $input `id $input` "
fi

4、写一个脚本/root/bin/yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息

read -p "pleae enter (yes|no|other):" input

if [ "$input" == "yes" ];then
    echo "user input a  yes"
elif [ "$input" == "no" ];then
    echo "user input a no"
elif [ "$input" == "other" ];then
    echo "user input a other"
fi

#######################################
case $input in 
[yY][eE][sS]|[yY])
    echo " user enter input is yes"
    ;;
[Nn][oO]|[nN])
    echo " user enter input is no"
    ;;

[oO][tT]|[oO])
    echo " user enter input is other"
    ;;
*)
    exit 2
    ;;
esac

5、写一个脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

read -p "please enter a filedir: " input

if [ -f $input ];then
    echo "the file is a general file"
elif [ -d $input  ];then
    echo "the file is a directory"
elif [ -h $input  ];then
    echo "the file is a lianjie file"
elif [ -b $input  ];then
    echo "the file is a kuaishebei file"
elif [ -p $input  ];then
    echo "the file is taojie fiel"
fi"

6、写一个脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

read -p "please enter a  num(int):"  int
 
if [ $int -le 0 &>/dev/null ];then
     echo "please enter a positive number!!" 
     exit 2
else
    expr $int + 0 &>/dev/null
    if [ $? -eq 0 ];then
       echo "user enter a num is int num "
    else
       echo " user enter a num is no int number" 
    fi
fi

7、判断/var/目录下所有文件的类型

DirName=/var/
filename=`ls -p $DirName`
for line   in $filename
do
      if [ -f $DirName$line ] ;then
        echo " $line is a file"
      elif [ -d $DirName$line ];then 
        echo "  $line is a dirstry"
       fi
done

8、 添加10个用户user1-user10,密码同用户名

addnum=[1..10]
for i in $addnum;
do
    id user$i  &>/dev/null 
    if [ $? -ne 0 ];then
        useradd user$i |passwd --stdin &>/dev/nul
        echo "the user$i useradd over!"
    else
        echo "Error:the user user$i  exits!

       read -p "dell exit user ?(yes|y| no)" inpu
        if [ $inpu == y ];then
            userdel -r user$i &>/dev/null
            echo "del user$i over!"
            useradd user$i |passwd --stdin &>/dev/nul
                    echo "the user$i always useradd over!"
        else
            exit 7
        fi
    fi
    
done

9、 /etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的文件输出为文件加stop,以S开头的文件输出为文件名加start;
“ K34filename stop”
“S66filename start”

dirname=/etc/rc.d/rc3.d/
dir=`ls $dirname`
for i in $dir
do
    alpha=`echo $i| grep -o "^[[:alpha:]]"`
    [ $alpha == "K" ] && echo "$i stop" 
    [ $alpha == "S" ] && echo "$i start"
done

10、写一个脚本,提示输入正整数n的值,计算1+2+3+…n的
总和

read -p "please enter a int number(n>0 ):" input

[ -z $input -a $input -lt 0  ] && echo " num is lt 0 , again enter  gt 0 !" && exit 2
sum=0
for i in `seq 1 $input`
do
     sum=$[$sum+$i ]
done
echo "1 to N has sum is: $sum"

11、 写一个脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态

#!/bin/bash
ip=10.1.252.
i=0
up=0
down=0
while [ $i -le  255  ]
do
    ping -c1 -w1 $ip$i &>/dev/null
    if [ $? -eq 0 ];then 
        echo -e " $ip$i host is \033[32mup\033[0m  " 
        up=$[$up+1]
    else
        echo -e "$ip$i host is \033[31mdown\033[0m  " 
        down=$[$down+1]
    fi
    
    let  i++;
done
echo  " up:$up dowm:$down"

12、 打印九九乘法表

for i in {1..9}
do
    for j in $(seq 1 $i)
    do
       echo -n -e  "${i}x${j}=$[$i*$j]\t"
    done
    echo
done

13、求100以内所有正整数之和

#1/bin/bash
i=0
s=0
while [ $i != 100 ]    
do
    i=$[ $i+1 ]
   sum=$[ $sum+$i ]


done
echo $sum
##############################
sum1=0
for  ((i=0;i<=100;i++))
do
sum1=$[$sum1+$i]

done

echo $sum1

14、通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态,统计在线主机和离线主机各多少。

15、while循环打印九九乘法表

i=1
j=1
while [ $i -le 9   ]
do
    while [ $j -le $i ]
    do
        echo -n -e  "${i}x${j}=$[$i*$j]\t"
    let j++
   
    done
        j=1
    echo
    
    let i++;
done

16、利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大者和最小者

##
i=0
max=0
min=100
while [ $i -lt 9  ]
do
    num=`echo $[RANDOM%100]`
    echo $num
     
    [ $min -gt $num ] && min=$num 
    [ $max -lt $num ] && max=$num 
    
    let i++
done
echo "big:$max  smail:$min "
unset i
unset max
unset min

17、打印国际象棋棋盘

############################################################方法一
#!/bin/bash
read -p "please enter a hang num:" hang
read -p "please enter a list num:" list
i=1
j=1
b="\033[40m  \033[0m"
w="\033[47m  \033[0m"
sum="" 

while [ $i -le $hang ]
do
    while [ $j -le  $list ] 
    do
      if [ $[$i%2] -gt 0 ];then
         [ $[$j%2] -eq 0 ] && sum=${sum}$b || sum=${sum}$w
      else
         [ $[$j%2] -gt 0 ] && sum=${sum}$b || sum=${sum}$w   
      fi
     
      let j++
    done
    
    echo -e "$sum"
    let i++
    j=1
    sum=""
done

###########################################################方法二

#!/bin/bash

read -p "  please enter a num(int): " LIE
read -p " please enter a num(int:)" HANG

a="\033[43m  \033[0m"
b="\033[40m  \033[0m"

JSH(){
        for((i=1;i<=${LIE};i++)){       
                [ $[$i%2] -eq 0 ] && echo -ne "$b" || echo -ne "$a"
                [ $i -eq ${LIE} ] && echo
        }
}

OSH(){
        for((j=1;j<=${LIE};j++)){       
                [ $[$j%2] -eq 1 ] && echo -ne "$b" || echo -ne "$a"
                [ $j -eq ${LIE} ] && echo
        }
}

for ((h=1;h<=$HANG;h++)){
        [ $[$h%2] -eq 1 ] && JSH || OSH
}

#####################################################方法三
#!/bin/bash

i=1

while [ $i -le 8 ];do
        j=1
        while [ $j -le 8 ];do
                sum=`expr $i + $j`
                z=`expr $sum % 2`
                [ $z -eq 0 ] && echo -ne "\033[41;1m  \033[0m"||echo -ne "\033[43;1m  \033[0m"
                let j++
        done
        echo
        let i++
done

18.每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并提示该用户退出系统。

#!/bin/bash
clear
username=wen
while true 
do
echo "3 min scan user login news"
sleep 1
echo -e "当前系统的用户登录信息:\n `who`" 

name=`who| grep "$username"` &>/dev/null
if [ $? -eq 0 ];then
	echo "发现$username用户登录,已记录该用户登录信息" 
 	$name >>  /var/log/login.log 
	echo " jilu over exit....."
	break
else
	echo "the $username is no login"
fi
done

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

#!/bin/bash
suiji=$[$RANDOM%10]
read -p " please enter a number:" shuru
until [[ $suiji -eq $shuru ]]; do
        #statements
        [ $shuru -lt $suiji ] && echo " $shuru is to smail" 
        [ $shuru -gt $suiji ] && echo "$shuru is to big"
        read -p "please enter a number:" shuru
done
echo "$shuru is == RANDOM, exit"

20.使用until循环

#!/bin/bash
i=1
until [ $i -gt 10 ]
do
	echo $i
	let i++
	[ $i -eq 5 ]&& exit
	echo ++++++++
done
echo xxx

21.使用while循环打印三角

[root@wen-7 shangkelianxi]# bash whilesanjiao.sh 
plesae a nun :6
     *
    ***
   *****
  *******
 *********
***********
[root@wen-7 shangkelianxi]# vim whilesanjiao.sh 

#!/bin/bash 
read -p "plesae a nun :" lie
for i in `seq $lie`
do
        for j in `seq $[ $lie-$i ]`
        do
                echo -n " "
        done
        for x in `seq $[ $[$i*2]-1]`
        do
                echo -n "*"
        done
        echo
done

原创文章,作者:wencx,如若转载,请注明出处:http://www.178linux.com/37224

(0)
wencxwencx
上一篇 2016-08-19
下一篇 2016-08-19

相关推荐

  • N25_第六周

    1、复制/etc/rc.d/rc.sysinit文件至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的行的行首加#; %s@^[[:space:]]+@#&@g 2、复制/boot/grub/grub.conf至/tmp目录中,删除/tmp/grub.conf文件中的行首的空白字符; %s@^[[:spac:]]+@@g…

    Linux干货 2017-02-13
  • 第十一周作业

    1、详细描述一次加密通讯的过程,结合图示最佳。 发送者:     1)使用单向加密算法提取要发送文件的特征码;     2)使用自己的私钥加密特征码并附加在数据后面;     3)生成用于对称加密的临时密码;     4)用此临时密钥加密数据和已经使用私钥加密后的特征码; &nb…

    2017-03-20
  • 如何用SHELL写好网络爬虫

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://nolinux.blog.51cto.com/4824967/1550976        上周,老大压下来任务,让写一个网络爬虫,负责爬某一个行业网站的数据信息。由于本人只会 sh…

    Linux干货 2016-08-15
  • 文本处理三剑客之grep及正则表达式

    文本处理三剑客之grep及正则表达式   文本处理工具:   Linux上处理文本三剑客:     Grep:文本过滤器工具(模式:pattern)工具;     Sed: stream editor,流编辑器;文本编辑工具;   &nbs…

    Linux干货 2016-08-12
  • 网络N23期第三周cut,last,awk,tr,sort,useradd,usermod,groupadd等命令使用练习

    1、列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。 [root@localhost ~]# who | cut -d '  ' -f1|uniq xinghuo root 2、取出最后登录到当前系统的用户的相关信息。 [root@localhost ~]# last -1  -a…

    Linux干货 2016-12-05
  • ☞awk

    awk

    Linux干货 2016-09-24