系统基础之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)
上一篇 2016-08-19 08:36
下一篇 2016-08-19 08:36

相关推荐

  • 马哥教育网络班22期+第6周课程练习

    请详细总结vim编辑器的使用并完成以下练习题 1、复制/etc/rc.d/rc.sysinit文件至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的行的行首加#; cp /etc/rc.d/rc.sysinit /tmp vim /tmp/rc.sysinit :%s@^[[:space:]]\+@…

    Linux干货 2016-09-19
  • 马哥教育网络班22期+第12周作业

    week11 1、请描述一次完整的http请求处理过程; 2、httpd所支持的处理模型有哪些,他们的分别使用于哪些环境。 3、源码编译安装LAMP环境(基于wordpress程序),并写出详细的安装、配置、测试过程。 4、建立httpd服务器(基于编译的方式进行),要求:      提供两个基于名称的虚拟主…

    Linux干货 2016-10-31
  • Linux进程篇16.3ps命令:进程管理工具

    ps命令:进程管理工具

    Linux干货 2017-12-18
  • N26-第三周

    1、列出当前系统上所有已经登录的用户的用户名,注意;同一个用户登录多次,则只显示一次即可。[root@localhost ~]# whoroot     tty1         2017-03-03 19:28root     pts/0     &nbsp…

    Linux干货 2017-03-04
  • linux下的文件查找命令对比(locate,find,grep,sed)

        在linux下,文件系统占据着非常重要的位置,而我们对于文件系统的操作也显得尤为重要。 如果我们想熟悉的操作文件系统,其中,我们需要对文本的查找,截取等命令需要熟悉的掌握。 这里就不得不说几个关于文本操作的几个命令的作用详细介绍和对比。比如: locate,find ,grep ,sed等。 这里,grep ,…

    Linux干货 2016-08-15
  • 文本处理工具及grep命令的理解与使用

    1. 文本处理工具   1.1 文件查看命令cat tac     cat命令:连接文件并在标准输出上面显示出来  图 1-1   cat帮助文档        cat [option]…[file]…     &n…

    Linux干货 2016-08-07