Linux操作系统shell脚本语言-第五章

一、流程控制

1、循环控制语句continue

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

格式:

for (());do
     循环体1
     ...
     if command2;then
         continue
     fi
     CMDn
     ....
done

示例: 结束最内层循环

#!/bin/bash
for((i=0;i<10;i++));do
   for((j=0;j<10;j++));do
          [ $j -eq 5 ] && continue
          echo $j
   done
  echo ----------------------------
 done

示例:结束外层循环

#!/bin/bash
for((i=0;i<10;i++));do
   for((j=0;j<10;j++));do
          [ $j -eq 5 ] && continue  2
          echo $j 
   done
  echo ----------------------------
 done
[root@ansible-salve1 shell]# vim info14.sh
[root@ansible-salve1 shell]# bash info14.sh 
0
1
2
3
4
0
1
2
3
4

2、循环控制语句break

break[N]:提前结束第N层后的全部循环;最内层为第1层,默认为1

示例:结束内层循环

#!/bin/bash
for((i=0;i<10;i++));do
   for((j=0;j<10;j++));do
          [ $j -eq 5 ] && break
          echo $j 
   done
  echo ----------------------------
 done
[root@ansible-salve1 shell]# vim info14.sh
[root@ansible-salve1 shell]# bash info14.sh 
0
1
2
3
4
----------------------------
0
1
2
3
4
----------------------------

示例:结束外层循环

#!/bin/bash
for((i=0;i<10;i++));do
   for((j=0;j<10;j++));do
          [ $j -eq 5 ] && break 2
          echo $j 
   done
  echo ----------------------------
 done
[root@ansible-salve1 shell]# vim info14.sh
[root@ansible-salve1 shell]# bash info14.sh 
0
1
2
3
4
[root@ansible-salve1 shell]# 

3、shift技术

shift命令用于对参数的向左移动,通常用于在不知道传入参数个数的情况下依次遍历每个参数,然后进行相应的处理(常见与Linux中各种程序的启动脚本)。在扫描处理脚本程序的参数时,经常要用到shift命令

shift命令每执行一次,参数序列顺次左移一个位置,$#的值减1,用于分别处理每个参数,移出去的参数不可再用

注意:$#表示脚本后跟随的参数总的个数,$n可以获取脚本后跟随的第n个参数的值

[root@nqs22-tps22 ~]# type shift
shift 是 shell 内嵌
[root@nqs22-tps22 ~]# help shift
shift: shift [n]
    移位位置参数。
    
    重命名位置参数 $N+1、$N+2 ... 到 $1、$2 ...  如果没有给定 N,
    则假设为1.
    
    退出状态:
    返回成功,除非 N 为负或者大于 $#。

2、Shell中的数组

1 Shell数组的概念

数组是若干数据的集合,其中存放的每一份数据都称为元素。Shell不限制数组的大小,理论上可以存放无限量的数据,Shell数组元素的下标也是从0开始计数

获取数组中的元素要使用下标[ ],下标可以是一个整数,也可以是一个结果为整数的表达式;下标必须大于等于0

注意:Shell只支持一维数组,不支持多维数组

2、Shell数组的定义

2.1、数组的基本定义

Shell中,用小括号()来表示数组,数组元素之间用空格来分隔

#arrayname=(1 2 3 4 5)
`输出定义数组中的全部元素
#echo ${arrayname[*]}
#echo ${arrayname[@]}
`输出定义数组中的第一个元素
#echo ${arrayname[0]}
`输出定义数组中的第二个元素
#echo ${arrayname[1]}
`输出定义数组中的元素个数
#echo ${#arrayname[*]}

2.2、采用键值对的形式赋值

Shell中用小括号将变量括起来,同时采用键值对的形式赋值

#array2=([1]=one [2]=two [3]=three)
echo ${array2[*]} #输出定义数组的所有元素
echo ${array2[@]} #输出定义数组的所有元素
echo ${#array2[@]} #输出定义数组的元素个数

2.3、通过分别定义数组变量的方法来定义

#array3[1]=a
#array3[2]=b
#array3[3]=c
`输出定义数组中的全部元素
echo ${array3[@]}
`输出定义数组中的第一个元素
echo ${array3[1]}

2.4、动态定义数组数量

动态地定义数组变量,并使用命令的输出结果作为数组的内容

# mkdir -p /array
# touch /array/{1..5}.txt
# ls /array
# array4=($(ls /array))
# echo ${array4[*]}
# echo ${array4[@]}
# echo ${#array4[*]}

3、Shell数组的打印

  • 打印单个数组元素: ${数组名[下标]} 。当未指定数组下标时,下标默认从0开始

  • 打印全部数组内容:${数组名[@]}或 ${数组名[*]}

  • 打印数组元素的个数:${#数组名[@]}或 ${#数组名[*]}

4、Shell数组的赋值

如果下标不存在,则自动添加一个新的元素;如果下标存在,则覆盖原来的值

5、Shell数组的拼接合并

所谓Shell数组拼接(数组合并),就是将两个数组连接成一个数组

拼接数组的思路是:先利用@或者*,将数组扩展成列表,然后再合并到一起,具体格式如下:

array_new=(${array1[@]} ${array2[@]})
array_new=(${array1[*]} ${array2[*]})
`两种方式是等价的,选择其一即可。其中,array1 和 array2 是需要拼接的数组,array_new 是拼接后形成的新数组。

示例:

#!/bin/bash
array1=(1 2 3 4 5)
array2=("https://www.baidu.com" "https://www.hehao.online" "https://www.taobao.com")
array_new=(${array1[*]} ${array2[*]})
echo ${array_new[@]}

--->结果
1 2 3 4 5 https://www.baidu.com https://www.hehao.online https://www.taobao.com

6、Shell删除数组元素

在Shell中,使用unset关键字来删除数组元素,具体格式如下:

unset array_name[index]
`其中,array_name表示数组名,index表示数组下标

unset array_name 
`删除整个数组

7、获取数组某范围的元素

Shell中直接通过${数组名[@/*]:起始位置:长度}获取数组给定范围内元素,返回字符串,中间用空格分开

#!/bin/bash
array=(yoona lucy tom)
echo ${array[*]}
echo ${array[*]:1:2}
echo ${array[@]:0:2}
-->结果为:
yoona lucy tom
lucy tom
yoona lucy

7.1、数组元素的替换

${数组名[@/*]/查找字符/替换字符}该操作不会改变原先数组内容,如果需要修改,使用覆盖

#!/bin/bash
array=(yoona lucy tom)
echo ${array[@]/lucy/lily}
echo ${array[*]}

--->结果为:
yoona lily tom
yoona lucy tom

8、关联数组

Bash支持关联数组,它可以使用字符串作为数组索引,有时候采用字符串索引更容易理解

8.1、定义关联数组

首先需要使用声明语句declare将一个变量声明为关联数组

# declare -A assArray

声明后,可以有两种方法将添加到关联数组中

1.利用内嵌索引-值列表的方法

# assArray=([lucy]=beijing [yoona]=shanghai)
# echo ${assArray[lucy]}

--->结果为:
beijing

2.使用独立的索引-值进行赋值

# assArray[lily]=shandong
# assArray[sunny]=xian
# echo ${assArray[sunny]}
-->结果为:xian

8.2 列出数组索引

每一个数组都有一个索引用于查找。使用${!数组名[@/*]}获取数组的索引列表

# echo ${!assArray[*]}
# echo ${!assArray[@]}

8.2 获取所有键值对

#! /bin/bash
declare -A cityArray
cityArray=([yoona]=beijing [lucy]=shanghai [lily]=shandong)
for key in ${!cityArray[*]}
do
  echo "${key} come from ${cityArray[$key]}"
done

--->结果为:
lily come from shandong
yoona come from beijing
lucy come from shanghai

9 mapfile命令

9.1、mapfile命令介绍

mapfile命令用于从标准输入读取行并赋值到数组

9.2、mapfile语法结构

mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]

选项介绍

`-d delim :将delim设为行分隔符,代替默认的换行符
`-n count :从标准输入中获取最多的count行,如果count为0那么获取全部
`-O origin:从数组下标为origin的位置开始赋值,默认的下标为0
`-s count: 跳过对前count行的读取
`-t : 读取时移除分隔符delim(默认为换行符)
`-u fd:从文件描述符fd中读取
`-C callback:每当读取了quantum行时,调用callback语句
`-c quantum:设定读取的行数为quantum
`array(可选):用于输出的数组名称。如果没有指定数组名称,那么会默认写入到变量名为MAPFILE的数组中

# 如果使用-C时没有同时使用-c指定quantum的值,那么quantum默认为5000。
#当callback语句执行时,将数组下一个要赋值的下标以及读取的行作为额外的参数传递给callback语句。
#如果使用-O时没有提供起始位置,那么mapfile会在实际赋值之前清空该数组

9.3、使用示例

`dns_list.txt
www.baidu.com
www.taobao.com
www.douyin.com
www.4399.com

[root@localhost Shell_Study]# mapfile array < dns_list.txt 
[root@localhost Shell_Study]# echo ${#array[*]}
4
[root@localhost Shell_Study]# echo ${array[#]}
[root@localhost Shell_Study]# echo ${array[@]}
www.baidu.com www.taobao.com www.douyin.com www.4399.com

二、Shell中的函数

1、Shell函数的定义

Shell函数的本质是一段可以重复使用的脚本代码,这段代码被提前编好了,放在了指定位置,使用时直接调用即可

Shell 中的函数和C++、Java、Python、C# 等其它编程语言中的函数类似,只是在语法细节有所差别。

Shell 函数定义的语法格式如下:

function name() {
  statements
  [return value]
}

对各个部分的说明:

  • function是 Shell 中的关键字,专门用来定义函数;

  • name是函数名;

  • statements是函数要执行的代码,也就是一组语句;

  • return value表示函数的返回值,其中 return 是 Shell 关键字,专门用在函数中返回一个值;这一部分可以写也可以不写。

{ }包围的部分称为函数体,调用一个函数,实际上就是执行函数体中的代码。

函数定义的简化写法

1.
name() {
    statements
    [return value]
}
2.
function name() {
    statements
    [return value]
}

2、Shell函数的调用

调用 Shell 函数时可以给它传递参数,也可以不传递。如果不传递参数,直接给出函数名字即可:

name

如果传递参数,那么多个参数之间以空格分隔:

name param1 param2 param3

不管是哪种形式,函数名字后面都不需要带括号。

和其它编程语言不同的是,Shell 函数在定义时不能指明参数,但是在调用时却可以传递参数,并且给它传递什么参数它就接收什么参数。

3、Shell函数详解

Shell中的函数在定义时不能指明参数,但是在调用时却可以传递参数。函数参数是Shell位置参数的一种,在函数内部可以使用$n来接收,例如:$1表示第一个参数,$2表示第二个参数,依次类推

除了$n,还有另外三个比较重要的变量:

  • $#可以获取传递的参数的个数;

  • $@或者$*可以一次性获取所有的参数

扩展:在Shell中 @ 与 @与 @与*的区别

在Shell脚本中,$*和$@是Shell脚本的特殊变量,作用都是获取传递给脚本或函数的所有参数

$@与$*的相同点:当它们没有被双引号包裹时,两者是没有区别的,都代表一个包含接收到的所有参数的数组,各个数组元素都是传入的独立参数

$@与$*的不同点:当被双引号包裹时,$@仍为一个数组,而$*会将所有参数整合成一个字符串

nginx启停脚本案例

#!/bin/bash
start(){
#当封装函数时,不能使用ps命令
        netstat -anptu | grep nginx &> /dev/null
        if [ $? -eq 0 ] 
        then
                echo "服务已经启动"
        else
                nginx
                echo "nignx服务正在启动...OK!"
        fi
}
stop(){
        netstat -anptu | grep nginx &> /dev/null
        if [ $? -ne 0 ]
        then
                echo "nginx服务已经关闭"

        else
                echo $?
                nginx -s stop
                echo "nignx服务正在关闭...OK!"
        fi
}
reload(){
        nginx -s reload
        echo "nignx服务正在重载...OK!"
}
restart(){
        nginx -s stop  &> /dev/null
        nginx
        echo "nignx服务正在重启...OK!"
}

case $1 in 
start)
        start
;;
stop)
        stop
;;
reload)
        reload
;;
restart)
        restart
;;
*)
        echo "USEAGE: $0 start | stop | reload | restart"
esac
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值