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 20:47
下一篇 2016-08-21 20:47

相关推荐

  • 运维工程师技能需求排行

    这是我今天在拉勾网搜索运维,翻完了4四页也招聘信息之后得到的,我的目的是想要看看之后的学习,哪个更应该成为重点,有些在我意料之中,有些还真的没想到,算是努力了一个小时的收获吧,分享给大家。
    注意:其中的看法仅代表个人观点,很多都是依靠我自己的学习经验和工作经验累积的

    Linux干货 2017-12-12
  • 数组和变量之间的关系及如何灵活运用数组

    什么是数组?数组:存储多个元素的连续的内存空间,相当于多个变量的集合什么是变量? 变量即是存储单个元素的内存空间 如果整个数组只有一个名字;数组名是数组的标识;也是数组所指向的存储多个元素的连续的内存空间开始地址的标识;数组索引定义从 0 开始(第一个数组元素);到 N 结束引用某个数组元素时,数组名+【索引】格式:${ARRAY_NAM…

    Linux干货 2017-05-22
  • 路由以及实验

    路由 路由(routing)是指分组从源到目的地时,决定端到路径的网络范围的进程。路由工作在OSI模型第三层——网络层的数据包转发设备。路由器通过转发数据包来实现网络互连。路由器可以支持多种协议,但绝大多数使用的是TCP/IP协议。路由器通常连接两个或者多个由IP子网或者点到点协议表示的逻辑端口,至少拥有1个物理端口。路由器根据收到数据包中的网络层地址以及路…

    Linux干货 2017-05-11
  • 磁盘管理

    1、创建一个10G分区,并格式为ext4文件系统。 (1)虚拟机添加21G硬盘 Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors Units = sectors of 1&nbsp…

    Linux干货 2016-12-18
  • 小型网站MYSQL问题二:Percona Xtrabackup实现数据库备份和恢复

    故事背景:前面大胆的选择了innodb,接下来就要考虑数据库的备份和恢复。俗话说“常在河边走,哪能不湿鞋“,自从接触数据这块,使我一直对它保持敬畏之心。在这里使用了percona公司的xtrabckup工具来实现数据库备份和恢复。操作步骤记录如下: 1、安装软件仓库(不要问我为什么不用源码安装,好吧,其实我懒。) wget https://www.…

    数据库运维 2015-12-19
  • Linux软件包管理之程序包编译安装

    程序包编译 程序包编译安装: Application-VERSION-release.src.rpm–>      安装后,使用rpmbuild命令制作成二进制格式的rpm包,而后再安装 源代码–>预处理–>编译(gcc)–>汇编&#82…

    Linux干货 2016-08-25

评论列表(1条)

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

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