shell编程2

组合测试条件

 第一种方式

       COMMAND1 && COMMAND2 并且

       COMMAND1 || COMMAND2 或者

       ! COMMAND 非

       如:[ -e FILE ] && [ -r FILE ]

 第二种方式

       EXPRESSION1 -a EXPRESSION2 并且

       EXPRESSION1 -o EXPRESSION2 或者

       ! EXPRESSION

       必须使用测试命令进行;

# [ -z “$HOSTNAME” -o $HOSTNAME "= =\"localhost.localdomain" ] && hostname www.QUAN.com 
判断hostname是否为空或者是否为localhost.localdomain,如果有一个条件成立,执行hostname命令
# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab判断文件是否存在并且可执行

   



课堂练习

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

首先vi /root/bin/per.sh编辑脚本

#!/bin/bash
[ -r /tmp/file1 -a -w /tmp/file1 ] && echo "`whoami` can read and write " || echo  "`whoami` can not read and write "

然后:wq存盘退出

blob.png

 2 、编写脚本/root/bin/nologin.sh 和login.sh, 实现禁止和充许普通用户登录系统。

vi /root/bin/nologin.sh

#!/bin/bash
[ -e /etc/nologin ] && exit || touch /etc/nologin
echo "disable user login "

vi /root/bin/login.sh

#!/bin/bash
[ -e /etc/nologin ] && rm -f /etc/nologin
echo "enable user login "

执行nologin脚本后,普通用户登录会出现:

blob.png

然后在执行login脚本,会恢复正常:

blob.png



使用read命令接受输入

    使用read 来把输入值分配给一个或多个shell 变量:

            -p 指定要显示的提示

            -t TIMEOUT

       read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量

 read -p “Enter a filename: “ FILE

条件选择if语句

      选择执行: 注意: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实例:

     根据命令的退出状态来执行命令

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

条件判断case语句

case 用变量引用 in

      PAT1)

           分支1

            ;;

      PAT2)

           分支2

            ;;

            …

       *)

         默认分支

            ;;

           esac

   case支持glob风格的通配符:

                    *: 任意长度任意字符

                    ?: 任意单个字符

                   []:指定范围内的任意单个字符

                   a|b: a或b



练习

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

vi /root/bin/createuser.sh

#!/bin/bash
if  id $1 &> /dev/null  ; then
     echo "$1 is exsit,the info is `id $1`"
else
    useradd $1 && echo "useradd is successful ,the info is `id $1`"
fi

blob.png

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

vi /root/bin/yesorno.sh

#!/bin/bash
echo -e "Do you agree marry me?yes or no:\c"
read answer
echo "your answer is $answer"

:wq存盘退出 执行yesorno脚本

blob.png

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

#!/bin/bash
read -p "please input a path of the file :" files
if [ -b $files ];then
    echo "该文件是块设备"
elif [ -c $files ] ;then
    echo "该文件是字符设备"
elif [ -f $files ];then
        echo "该文件是普通文件"
elif [ -h $files ];then
        echo "该文件是符号链接文件"
elif [ -p $files ];then
        echo "该文件是管道文件"
elif [ -S $files ];then
        echo "该文件是套接字文件"
elif [ -d $files ];then
        echo "该文件是目录文件"
else
    echo "文件或目录不存在"
fi

:wq存盘退出,执行脚本

blob.png

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

vi /root/bin/checkint.sh

!/bin/bash
read -p "please input :" arg
if  [[ $arg =~ ^[[:digit:]]+$  ]] && [ $(expr $arg + 0)  != 0  ]    
;then
    echo "The number is positive integer"
else
    echo "The number is not positive integer"
fi

:wq 存盘退出,执行脚本

blob.png



   循环      

     循环执行

           将某代码段重复运行多次

           重复运行多少次:

                循环次数事先已知

                循环次数事先未知

                有进入条件和退出条件

         for, while, until

     for循环

           for 变量名 in 列表;do

           循环体

           done

           执行机制 :

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

     列表生成方式

           (1) 直接给出 列表

           (2) 整数列表:

           (a) {start..end}

           (b) $(seq [start [step]] end)

           (3) 返回列表的命令

                $(COMMAND)

           (4) 使用glob,如:*.sh

           (5) 变量引用;

                          $@, $*


 


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

#!/bin/bash
# Version: 0.1
# Description: Batch to create user
#        1.File to import
#        2.user1-user10 
if [ -s userfile.t ]; then
        for i in $(cat userfile.t)
        do
                useradd $i
                echo $i | passwd --stdin $i > /dev/null
        done
        echo "The user has been created"
else
        for i in $(seq 1 10)
        do
                useradd user$i
                echo user$i | passwd --stdin user$i > /dev/null
        done
        echo "The user has been created"
fi

然后执行下脚本

blob.png

如果重复执行脚本,会出现下面的提示

blob.png

     创建一个删除脚本

#!/bin/bash
# Version: 0.1
# Description: Batch delete user
#        1.File to import
#        2.user1-user10 
if [ -s userfile.t ]; then
        for i in $(cat userfile.t)
        do
                userdel -r $i > /dev/null
        done
        echo "The user has been deleted"
else
        for i in $(seq 1 10)
        do
                userdel -r user$i > /dev/null
        done
        echo "The user has been deleted"
fi

   执行脚本看一下:

blob.png

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

编辑脚本,vi file-rc3.d

#!/bin/bash
for file in `ls /etc/rc.d/rc3.d`;do
        if echo $file | grep -q "^S" ;then
                echo "$file start"
        elif echo $file | grep -q "^K" ;then
                echo "$file stop"
        fi
done

blob.png

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

#!/bin/bash
read -p "please input a number:" n
sum=0
for i in $(seq 1 $n);do
    let sum+=$i
done
echo "the sum is $sum"

   执行脚本 输入的数字表示的是 从1开始的n个数字 执行脚本相加求和

blob.png

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

#!/bin/bash
file=`mktemp /tmp/pingip.XXXXXX`
read -p "please input the ip adress :" ip
i=`echo $ip | cut -d'.' -f1-3`
for z in {1..255};do
{
    ip=$i.$z
    ping -c1 -W1 $ip &> /del/null && (echo "$ip is up" ) && echo ip>
> $file
}&
done
sleep 1
echo "`cat $file | wc -l`online"
rm -f $file &> /dev/null

打印九九乘法表

#!/bin/bash
for i in {1..9};do
    for j in $(seq 1 $i) ;do
      echo -ne "${j}x${i}=$[i*j]\t"
    done
    echo
done

blob.png



     while循环

        while CONDITION; do

                       循环体

                  done

       CONDITION :循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true” ,则执行

       一次循环;直到条件测试状态为“false” 终止循环

     因此:CONDTION 一般应该有循环控制变量;而此变量的值会在循环体不断地被修正

       进入条件:CONDITION 为true; ;

       退出条件:CONDITION 为false



  练习

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

sum=0
i=0
while [ $i -le 100 ] ;do
    let sum+=$i
    let i++
    done
echo $sum

blob.png

2、打印九九乘法表

#!/bin/bash
i=1
j=1
while [ $i -le 9 ] ;do
    while [ $j -le $i  ] ;do
        echo -ne "${j}x${i}=$[i*j]\t"
        let j+=1
    done
    let i+=1
    j=1
    echo
done

blob.png

3、打印国际象棋棋盘

#!/bin/bash
for i in $(seq 1 8);do
for j in $(seq 1 8);do
[ $[i%2-$j%2] -eq 0 ] &&  echo -ne "\033[44m  \033[0m" ||  echo -ne 
"\033[47m  \033[0m"
let j++
done
echo ""
let i++
done

blob.png

#!/bin/bash
let x=y=1
h=8
while [ $x -le $h ];do
    while [ $y -le $h ];do
        if [ $[(x+y)%2] -eq 0 ]  ;then
            echo -en "\033[41m  \033[0m"
        else
            echo -en "\033[47m  \033[0m"
        fi
    let y+=1
    done
    echo
let x+=1,y=1
done

blob.png

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

#!/bin/bash
let i=0,min=max=$RANDOM
echo "$min "
while [ $i -lt 9  ];do
    ran=$RANDOM
    echo "$ran "
    if [ $ran -ge $max ];then 
        let max=ran
    fi
    if [ $ran -le $min ];then
        let min=ran
    fi
    let i+=1
done
echo "the max is $max ,the min is $min"

blob.png



until循环  

        until CONDITION; do

            循环体

         done

        :进入条件:CONDITION 为false

        :退出条件:CONDITION 为true

循环控制语句continue 

      用于循环体中

      continue [N] :提前结束第N 层的本轮循环,而直接进入下一轮判断;最内层为第1层

while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
done

控制循环语句break

         用于循环体中

         break [N] :提前结束第N 层循环,最内层为第1层

while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
done

创建无限循环:

      while true; do

        循环体

        done

      until false; do

        循环体

         Done

练习

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

#!/bin/bash
lim=10
let key=$RANDOM%lim
read -p  "please input a number less than $lim: " num
until false;do
    if [ $num -le $lim &> /dev/null  ] && [ $num -ge 0  &> /dev/null] ;then
        if [ $num -lt $key ];then
            read -p "is small,please input again: " num
        elif [ $num -gt $key ];then
            read -p "is big,please input again: " num
      else
            echo "you are right,man gave me five"
            break
        fi
    else
        read -p  "error,please input a number less than ten: " num
    fi
done

   

blob.png



特殊用法

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

                 while read line; do

                       循环体

                 done < /PATH/FROM/SOMEFILE

依次读取/PATH/FROM/SOMEFILE 文件中的每一行,且将行赋值给变量line

       双小括号方法,即((…)) 格式,也可以用于算术运算

       双小括号方法也可以使bash Shell 实现C 语言风格的变量操作

            #I=10

            #((I++))

       for循环的特殊格式:

       for(( 控制变量初始化; 条件判断表达式; 控制变量的修正表达式))

       do

            循环体

       done

      控制变量初始化:仅在运行到循环代码段时执行一次

      控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

原创文章,作者:旧城以西,如若转载,请注明出处:http://www.178linux.com/35755

(0)
旧城以西旧城以西
上一篇 2016-08-21
下一篇 2016-08-22

相关推荐

  • LVS负载均衡初接触

    Linux Cluster : Cluster : 计算机集合, 为解决某个特定问题组合起来形成的单个系统; Linux Cluster 类型 : LB : Load Balancing, 负载均衡;()HA : High Avaiibality, 高可用;( 通过冗余的方式让活动主机出现问题时取而代之, 并具有原主机一致的功能)HP : High Perf…

    Linux干货 2016-10-28
  • linux运维

    linux运维大纲,学习路线图

    Linux干货 2017-10-21
  • 7-26第三课-帮助和bash基础命令

     命令:     1.获取帮助 内部命令     #help COMMAND     #man COMMAND 外部命令     # COMMAND …

    Linux干货 2016-07-29
  • 通过堡垒机代理SSH运行Ansible(译)

    有一种常见的网络安全模式是阻止私有网络外部对应用服务器的所有连接(指除了业务数据外其它的连接,如后台管理系统和内部业务系统。译者注),然后使用 DMZ 区域中的 堡垒机 来选择性的将到服务器的流量加入白名单。 我们有这样的一个服务器池,只允许来自特定 IP 地址的 SSH 流量。这些服务器还由 Ansible…

    Linux干货 2015-02-14
  • M22 xfs文件系统命令总结

    Centos6.0及之前的默认文件系统是ext系列的,而在最新的Centos7上却使用了xfs作为默认的文件系统。在Centos7中xfs文件系统包括如下命令: xfs_admin:修改xfs文件系统的参数,需要先卸载分区 用法:xfs_admin [ -eflpu ] [ -c 0|1 ] [ -L label ] [ -U uuid ] device x…

    Linux干货 2017-03-16
  • iptables

    Evernote Export   基于本机服务器的iptables: 创建、重命名、删除自定义chain ~]# iptables -N testchain ~]# iptables -nL Chain INPUT (policy ACCEPT) target     prot opt source    …

    Linux干货 2016-11-20

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-21 23:08

    shell脚本作为一个基本能力,需要我们多加练习,才能熟练掌握,我们可以通过写的练习总结出各个循环语句的区别,来实现对循坏语句的快速选择和应用。