系统基础之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

相关推荐

  • Lvs+keepalived+httpd+NFS搭建高可用

    自己捯饬的模型图 NAT模型图 注意事项:RealServer需要把网关指向Director,并且Director要打开转发功能命令如下:     echo "1" > /proc/sys/net/ipv4/ip_foreward DR模型图 注意事项:需要在RealServer配置…

    Linux干货 2016-10-25
  • 20160808课堂练习(sed工具)

    练习: 1、  删除/etc/grub2.conf文件中所有以空白开头的行行首的空白字符 # sed 's@^[[:space:]]\+@@' /etc/grub2.cfg                    2、删除/etc/…

    Linux干货 2016-08-10
  • Shell脚本编程基础

    1编程基础 程序:指令+数据 程序编程分格: 过程式:以指令为中心,数据服务于指令 对象式:以数据为中心,指令服务于数据 Shell程序:提供了编程能力,解释执行 程序的执行方式 计算机:运行二进制指令 编程语言: 低级:汇编 高级:编译:高级语言->编译器->目标代码 编译性语言编写的程序通常是需要通过编译器去转换成计算机可以识别的二进制文件,…

    2017-11-27
  • 第三周作业

    1、列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。       首先用who命令列出当前系统上所有登陆用户,然后使用cut命令以空格为分隔符取出第一列,再使用sort排序并去除重复的行        …

    Linux干货 2017-01-18
  • linux基础入门之一

    一、计算机的组成与功能 计算机由硬件和软件组成 硬件: 按冯·洛伊曼体系划分 1、CPU:包括运算器、控制器、寄存器、缓存,对数据控制和计算 2、存储器:内部存储器、外部存储器,对数据提供存储功能 3、输入设备:具有下指令,提供数据输入 4、输出设备:输出数据加工的结果 软件: 1、低级语言:汇编语…

    Linux干货 2016-09-19
  • N26-肉肉-第二周作业

    1、Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示。 常用文件管理命令有cp,mv,rm  cp :copy        -i:交互式复制,覆盖之前提醒用户确认;         &n…

    Linux干货 2017-01-03