第二十一章 结构化命令case和for,while 循环

本节所讲内容

21,1  case - 流程控制语句

21.2   循环循环语句

21.3  循环语句嵌套

21.4  实战-3个shell脚本实战

21.1 流程控制语句

控制语句:

case  变量值  in

    变量或者表达式1 ) 

    命令序列1

   ;;

    变量或者表达式1 )

    命令序列2

;;

.........

*)

默认命令序列

esac  

case   语句执行流程控制


例1  编写一个操作文件的脚本

  ################################################

#  File  Name :  case-1.sh

Author:xuegod

   ############################################################

#! /bin/bash

cat <<eof 

********************

** 1.backup

** 2.copy

** 3.quit

1)[root@localhost ~]# vim case-1.sh

2)#! /bin/bash

######################################################################################################3

# File Name: case-1.sh

# Author: xuegod

######################################################################################################3

cat <<eof

**************

** 1.backup **

** 2. copy  **

** 3. quit  **

**************

eof

read -p "Input your choose:" OP

case $OP in

        1|backup)

        echo "BACKUP"

        ;;

        2|copy)

        echo "COPY"

        ;;

        3|quit)

        exit

        ;;

        *)

echo    error

esac

3) [root@localhost ~]# bash case-1.sh

**************

** 1.backup **

** 2. copy  **

** 3. quit  **

**************

例2  : 编写一个启动Apache  脚本

1)[root@localhost ~]# yum -y install httpd

2)[root@localhost ~]# vim case2-.sh

3) #! /bin/bash

case $1 in

start )

        systemctl $1 httpd

        ps  aux | grep httpd

        echo "httpd start"

        ;;

stop)

        systemctl $1 httpd

        ps  aux | grep httpd

        echo "httpd stop"

        ;;

status)

        systemctl $1 httpd

        ;;

rstart)

        systemctl $1 httpd

        echo "httpd restart"

        ;;

*)

        echo "USAGE: $0        start| stop| restart"

esac


4)[root@localhost ~]# systemctl start httpd

5) [root@localhost ~]# bash case2-.sh start

root      13694  0.4  0.2 224056  5008 ?        Ss  20:58  0:00 /usr/sbin/httpd -DFOREGROUND

apache    13697  0.0  0.1 226140  3096 ?        S    20:58  0:00 /usr/sbin/httpd -DFOREGROUND

apache    13698  0.0  0.1 226140  3096 ?        S    20:58  0:00 /usr/sbin/httpd -DFOREGROUND

apache    13699  0.0  0.1 226140  3096 ?        S    20:58  0:00 /usr/sbin/httpd -DFOREGROUND

apache    13700  0.0  0.1 226140  3096 ?        S    20:58  0:00 /usr/sbin/httpd -DFOREGROUND

apache    13701  0.0  0.1 226140  3096 ?        S    20:58  0:00 /usr/sbin/httpd -DFOREGROUND

root      13717  0.0  0.0 112712  944 pts/1    R+  20:58  0:00 grep httpd

21.2   循环语句

  21.2.1  for-do-done

   语法格式

for  var in list

do  

commands

done

或 

for var in list ; do

commands

done


取值列表有多种取值方式;比如

可以直接读取in  后面的值,默认以空格分隔

例1

1)[root@localhost ~]# vim for-1.sh

2)

#! /bin/bash

for var in a1 b1 c1 d1

do

        echo the text is $var

done

~     

3) [root@localhost ~]# bash for-1.sh

the text is a1

the text is b1

the text is c1

the text is d1

列表中的复杂值,可以使用引号或者转义符 ”/”  来加以约束

1)[root@localhost ~]# vim for-2.sh

2)#! /bin/bash

for var in a1 b1 "c1 d1" e2 "hello world"

do

        echo    $var

done

还要一种的转义符

#! /bin/bash

for var in a1 b1\'1 "c1 d1 e2 hello world" I\'s a22

do

        echo    $var

done

3)[root@localhost ~]# bash for-2.sh

a1

b1

c1 d1

e2

hello world

例子4 

1)vim   for-4.sh

2)
#! /bin/bash

list="a1 b1 c1 d1"

for i in $list

do

        echo is a $i

done

3)

[root@localhost ~]# bash for-4.sh

is a a1

is a b1

is a c1

is a d1

从变量中取值

cat  for-4.sh

#! /bin/bash

list="a1 b1 c1 d1"

for i in $list

do

        echo is a $i

done

4 从命令中取值

[root@localhost ~]# cat /etc/hosts

127.0.0.1  localhost localhost.localdomain localhost4 localhost4.localdomain4

::1        localhost localhost.localdomain localhost6 localhost6.localdomain6

①[root@localhost ~]# vim for-5.sh

②#! /bin/bash

for i in `cat /etc/hosts`

do

        echo $i

done

~   

③ [root@localhost ~]# bash for-5.sh

127.0.0.1

localhost

localhost.localdomain

localhost4

localhost4.localdomain4

::1

localhost

localhost.localdomain

localhost6

localhost6.localdomain6

5 自定义shell分隔符

默认情况下,bash  shell  会以空格,制表符,换行符作为分隔符,哦通过IFS来自定义分隔符

指定单个字符做分隔符

IFS=: #以:  冒号做分隔符

可以指定多个

如  IFS='\n':;"   #   这个赋值会将反斜杠,n,冒号,分号,双引号作为字段分隔符

注:$'\n'  与'\n' 时的区别

IFS='\n'  #   将字符\  和字符n  作为IFS   的换行符

IFS=$'\n'  # 真正使用换行符作为分隔符

cat   for-6.sh   指定以\n   回车代表作为for语句分隔符

①  vim  for-6.sh 

②#! /bin/bash

IFS=$'\n'

for i in `cat /etc/hosts`

do

        echo $i

done

③ [root@localhost ~]# bash for-6.sh

127.0.0.1  localhost localhost.localdomain localhost4 localhost4.localdomain4

::1        localhost localhost.localdomain localhost6 localhost6.localdomain6

例7  以冒号作为分隔符

改变其中的shell脚本就行

#! /bin/bash

IFS=: 

for i in `cat /etc/hosts`

do

        echo $i

done

6   C 语句风格的for

  语法格式

for  ((i=0;i<10;i++))

do  

commands

done

例1;单个变量。输出1到10 之间的数字

①[root@localhost ~]# vim for-8.sh

#! /bin/bash

for (( i=1; i<=10;i++))

do

        echo num is $i

done

~     

③[root@localhost ~]# bash for-8.sh

num is 1

num is 2

num is 3

num is 4

num is 5

num is 6

num is 7

num is 8

num is 9

例2  

①[root@localhost ~]# vim for-9.sh

②   #! /bin/bash

for ((a=1,b=9;a<10;a++,b--))

do

        echo  num is $a ------ $b

done

③[root@localhost ~]# bash for-9.sh

num is 1 ------ 9

num is 2 ------ 8

num is 3 ------ 7

num is 4 ------ 6

num is 5 ------ 5

num is 6 ------ 4

num is 7 ------ 3

num is 8 ------ 2

num is 9 ------ 1

21.3  while  循环语句和循环嵌套

重复测试指令的条件   只要条件成立就反复执行对应的命令操作,直到命令不成立或为假

语法格式如下

while 测试命令

do 

命令

done


注意: 避免陷入死循环,  while   true

①[root@localhost ~]# vim for-10.sh

②#! /bin/bash

var=10

while [ $var -gt 0 ]

do

        echo $var

        var=$[ $var-1 ]

done

③[root@localhost ~]# bash for-10.sh

10

9

8

7

6

5

4

3

2

1

①[root@localhost ~]# vim while2.sh

②#! /bin/bash

num=1

while [ $num -lt 10 ]

do

        sum=$(( $num * $num ))

        echo "$num * $num=$sum"

        ((num++))

#      let num++

done

③ [root@localhost ~]# bash while2.sh

1 * 1=1

2 * 2=4

3 * 3=9

4 * 4=16

5 * 5=25

6 * 6=36

7 * 7=49

8 * 8=64

9 * 9=81

自增操作 let var  ++

自减操作 let var --

21.3.2  嵌套循环

九九乘法表

   例1  :批量添加a.txt  文件中的5个用户

1   编写脚本的思路

 2 编写脚本会用到哪些命令    useradd  passwd   chage  for

 3   把变化的数据变量表示

 4  选择合适的流程控制  选择  循环   分支

①vim  a.txt

②mk1

ls1

ab1

df1

ni1

③[root@localhost ~]# vim for-add.sh

#! /bin/bash

for name in `cat /root/a.txt`

#for name in $(cat /root/a.txt)

do

        id $name &> /dev/null

        if [ $? -ne 0 ];then

              useradd $name

              echo "123456" | passwd --stdin $name &> /dev/null

              echo "user $name create"

else

              echo "user $name is exits"

        fi

done

⑤[root@localhost ~]# bash for-add.sh

user mk1 create

user ls1 create

user ab1 create

user df1 create

user ni1 create

例2   打印九九乘法表

注意  外层循环行,内层循环

①[root@localhost ~]# vim 99.sh

②#! /bin/bash

for i in `seq 9`

do

      for j in `seq 9`

        do

      [ $j -le $i ] && echo -n "$i*$j=  `echo $(($i*$j))`"

      done

        echo "    "

done

③[root@localhost ~]# bash 99.sh

1*1=  1   

2*1=  22*2=  4   

3*1=  33*2=  63*3=  9   

4*1=  44*2=  84*3=  124*4=  16   

5*1=  55*2=  105*3=  155*4=  205*5=  25   

6*1=  66*2=  126*3=  186*4=  246*5=  306*6=  36   

7*1=  77*2=  147*3=  217*4=  287*5=  357*6=  427*7=  49   

8*1=  88*2=  168*3=  248*4=  328*5=  408*6=  488*7=  568*8=  64   

9*1=  99*2=  189*3=  279*4=  369*5=  459*6=  549*7=  639*8=  729*9=  81 


①vim  log .sh


#!/bin/bash

SRC_DIR=/var/log/

DES_DIR=/opt/backup/`date +%Y%m%d`

if

[ ! -d  $DES_DIR ] ; then

        mkdir -p $DES_DIR

fi

for i in  `find  $SRC_DIR  -name "*.log"`

do

        tar  czf  $i.tgz  $i

done

mv /var/log/*.tgz $DES_DIR

ls -lh $DES_DIR

echo "The scripts exec end, Files tar successfully !"

③[root@localhost ~]# bash log.sh

mkdir: cannot create directory ‘/opt/backup’: Not a directory

tar: Removing leading `/' from member names

tar: Removing leading `/' from member names

tar: Removing leading `/' from member names

tar: Removing leading `/' from member names

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容