Linux系统Shell编程及自动化运维实现-数组和函数

Linux系统Shell编程及自动化运维实现-数组和函数

  • 一.数组
    • 1.数组简介
    • 2.类型
    • 3.普通数组
      • 3.1定义数组
      • 3.2访问数组元素
    • 4.关联数组
      • 4.1定义关联数组
      • 4.2访问数组元素
    • 5.数组和循环
    • 6.案例
  • 二.函数
    • 1.概述
    • 2.定义函数
    • 3.调用函数
    • 4.示例
      • 4.1示例1:初识函数
      • 4.2示例2:阶乘函数(传参)
      • 4.3示例3:函数传参 数组传参
      • 4.4示例4:函数结果 赋予数组
  • 三.影响shell程序的内置命令
    • 1.概览
    • 2.continue/break/shift

一.数组

1.数组简介

  • 变量:用一个固定的字符串,代替一个不固定字符串。
  • 数组:用一个固定的字符串,代替多个不固定的字符串。

2.类型

  • 普通数组:只能使用整数作为数组索引
  • 关联数组:可以使用字符串作为数组索引
  • 图示:
    Linux系统Shell编程及自动化运维实现-数组和函数_第1张图片
  • 总结:变量切片有个索引的概念。一个索引(整数)对应一个字符。
    普通数组:数组中的索引对应一个字符串。
    关联数组:数组中的索引可以使用字符串。

3.普通数组

3.1定义数组

  • 方法一:一次赋一个值
数组名[下标]=变量值
[root@localhost ~]# array1[0]=aaa
[root@localhost ~]# array1[1]=bbb
[root@localhost ~]# array1[2]=ccc
[root@localhost ~]# declare -a | grep array1
declare -a array1='([0]="aaa" [1]="bbb" [2]="ccc")'
[root@localhost ~]# echo ${array1[@]}
aaa bbb ccc
  • 方法二:一次赋多个值
[root@localhost ~]# array2=(a1 b1 c1)
[root@localhost ~]# echo ${array2[@]}
a1 b1 c1
[root@localhost ~]# array3=(`cat /etc/passwd`)
[root@localhost ~]# array4=(`ls /var/ftp/shell/for*`)
[root@localhost ~]# array5=(tom jack alice "bash shell")
[root@localhost ~]# echo ${array5[*]}tom jack alice bash shell
[root@localhost ~]# colors=($red $green $blue $recolor)
[root@localhost ~]# array6=(1 2 3 4 5 6 7 "linux shell" [20]=saltstack)

3.2访问数组元素

访问数组元数:
[root@localhost ~]# echo ${array1[0]}   #访问数组中的第一个元数
[root@localhost ~]# echo ${array1[@]}   #访问数组中所有元数 等同于 echo ${array1[*]}
[root@localhost ~]# echo ${#array1[@]}  #统计数组元素的个数
[root@localhost ~]# echo ${!array1[@]}  #获取数组元素的索引
[root@localhost ~]# echo ${array1[@]:1} #从数组下标1开始
[root@localhost ~]# echo ${array1[@]:1:2}   #从数组下标1开始,访问两个元素

4.关联数组

4.1定义关联数组

  • 必须先声明关联数组
  • 方法一:一次赋一个值
[root@localhost ~]# declare -A array
[root@localhost ~]# array[a1]=aaa
[root@localhost ~]# array[a2]=bbb
[root@localhost ~]# array[a3]=ccc
[root@localhost ~]# echo ${array[@]}
ccc bbb aaa
[root@localhost ~]# array[a3]=ddd
[root@localhost ~]# echo ${array[@]}
ddd bbb aaa
  • 方法二:一次赋多个值
[root@localhost ~]# declare -A array[root@localhost ~]# array=([a]=tom [b]=bob [c]=jack) 
[root@localhost ~]# array=([a]=tom [b]=bob [c]=jack [d]='bash shell')
[root@localhost ~]# echo ${array[@]}tom bob jack bash shell
[root@localhost ~]# echo ${array[d]}
bash shell

4.2访问数组元素

[root@localhost ~]# echo ${ass_array2[index2]} #访问数组中的第二个元数
[root@localhost ~]# echo ${ass_array2[@]} #访问数组中所有元数 等同于 echo ${array1[*]}
[root@localhost ~]# echo ${#ass_array2[@]} #获得数组元数的个数
[root@localhost ~]# echo ${!ass_array2[@]} #获得数组元数的索引

5.数组和循环

  • 1.通过循环定义和显示数组
  • 2.通过数组统计数据

6.案例

  • 案例1:while脚本快速定义数组
[root@localhost ~]# cat array.sh 
#!/bin/bash
#循环读取文件,定义数组
while read line
do
#hosts:数组名
#[++i]:索引递增,++i是1开始,i++是0开始。
#$line:值,即文件中的内容
hosts[++i]=$line
done < /etc/hosts
#输出索引每一行
for i in ${
     !hosts[@]}
do
echo "$i  :   ${hosts[$i]}"
done

[root@localhost ~]# bash array.sh 
1 :127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
2 : ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
  • 案例2:for脚本快速定义数组
[root@localhost ~]# vim array-for.sh 
#!/bin/bash
#OLD_IFS=$IFS
#IFS=$'\n'
for line in `cat /etc/hosts`
do
        hosts[i++]=$line
done
for i in ${
     !hosts[@]}
do
        echo "$i---"
        echo "${hosts[$i]}"
done
#IFS=$OLD_IFS

[root@localhost ~]# bash array-for.sh 
0---
127.0.0.1
1---
localhost
2---
localhost.localdomain
3---
localhost4
4---
localhost4.localdomain4
5---
::1
6---
localhost
7---
localhost.localdomain
8---
localhost6
9---
localhost6.localdomain6

---解决for循环的空格分割问题:IFS=$'\n'---

[root@localhost ~]# vim array-for.sh 
#!/bin/bash
OLD_IFS=$IFS   #讲旧的分隔符备份
IFS=$'\n'   #定义for的分隔符是换行符
for line in `cat /etc/hosts`
do
        hosts[i++]=$line
done
for i in ${
     !hosts[@]}
do
        echo "$i---"
        echo "${hosts[$i]}"
done
IFS=$OLD_IFS   #将分隔符还原,便于脚本后方的for使用

  • 案例3:数组统计性别
---1.定义性别文本---

[root@localhost ~]# vim sex.txt
jack m
alice f
tom m

---2.定义脚本统计性别---

[root@localhost ~]# vim sex.sh
#!/bin/bash
declare -A sex
while read line
do
        type=`echo $line|awk '{print $2}'`
        let sex[$type]++
done < sex.txt

for i in ${
     !sex[@]}
do
        echo "$i : ${sex[$i]}"
done

---3.测试脚本---

[root@localhost ~]# bash sex.sh 
f : 1
m : 2
  • 案例4:使用数组统计,用户shell的类型和数量
[root@localhost ~]# vim passwd.sh 
#!/bin/bash
declare -A shells
while read ll
do
type=`echo $ll | awk -F: '{print $NF}'`
let shells[$type]++
done < /etc/passwd
for i in ${
     !shells[@]}
do
echo "$i : ${shells[$i]}"
done

[root@localhost ~]# bash passwd.sh 
/sbin/nologin : 39
/bin/sync : 1
/bin/false : 1
/bin/bash : 6
/sbin/shutdown : 1
/sbin/halt : 1

二.函数

1.概述

  • 概念:函数是一段完成特定功能的代码片段(块)
    在shell中定义了函数,就可以使代码模块化,便于复用代码
    注意函数必须先定义才可以使用。
  • 重点:传参 $ 1,$ 2
    局部变量 local
    返回值 return 即$ ?

2.定义函数

  • 方法一:
    函数名(){
    函数要实现的功能代码
    }
  • 方法二:
    function 函数名{
    函数要实现的功能代码
    }

3.调用函数

  • 语法
    函数名
    函数名 参数1 参数2

4.示例

4.1示例1:初识函数

--- 需求 ---

编写循环脚本,功能菜单
provide these tools:
show disk info(d)
show mem info(m)
show cpu info(c)
quit(q)

--- 思路 ---

1.编写菜单和判断
2.添加循环
3.添加函数

--- 演示1 ---

[root@localhost ~]# vim menu.sh
#!/bin/bash
show_menu() {
     
cat << EOF
provide these tools:
show disk info(d)
show mem info(m)
show cpu info(c)
quit(q)
EOF
}

while :
do

show_menu
read -p "Input choice: " choice
case $choice in
d)
	echo "===========disk info=============="
	df -hT
;;
m)
	echo "==========meme info==============="
	free -m
;;
c)
	echo "==========cpu info================="
	uptime
;;
q)
	break
;;
*)
	show_menu
;;
esac

done

4.2示例2:阶乘函数(传参)

--- 需求 ---

制作函数用于阶乘

--- 思路 ---

1.了解阶乘概念
2.定义函数
3.引用函数

--- 演示 ---

[root@localhost ~]# vim factorial.sh
#!/bin/bash
fun(){
     
factorial=1
for((i=1;i<=$1;i++))   #等同于for i in `seq $i`
do
factorial=$[$factorial*$i]
done
echo "$1 阶乘: $factorial"
}
fun $1

4.3示例3:函数传参 数组传参

--- 1.阶乘脚本,通过数组给函数传参

[root@localhost ~]# vim array3.sh 
#!/bin/bash
num=(1 2 3)
num2=(4 5 6)
array(){
     
factorial=1
for i in $*
do
factorial=$[factorial*$i]
done
echo $factorial
}
array ${
     num[*]}
array ${
     num2[*]}

--- 2.数组好处在于多个数组时传参效率增高 ---

4.4示例4:函数结果 赋予数组

--- 1.通过函数输出到数组 ---

[root@localhost ~]# vim array4.sh
#!/bin/bash
num=(1 2 3)
array(){
     
for i in $*
do
outarray[j++]=$[$i+5]
done
echo "${outarray[*]}"
}
result=`array ${
     num[*]}`
echo ${
     result[*]}

--- 2.函数不仅可以从数组中调取值,还可以赋予数组值

三.影响shell程序的内置命令

1.概览

:
true
false
exit
break
continue
shift

————————————————————————————————————————————————

shift 使位置参数向左移动,默认移动1位,可以使用shift 2
exit 退出整个程序
break 结束当前循环,或跳出本层循环
continue 忽略本次循环剩余的代码,直接进行下一次循环

2.continue/break/shift

--- 1.需求:通过循环脚本实现如下效果 ---

  A123456789
  B123456789
  C123456789
  D123456789

--- 2.编写循环脚本 ---

[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
     A..D}
do
        echo $i
        for j in {
     1..9}
        do
                echo $j
        done
done

--- 3.测试脚本,观察结果 ---

[root@localhost ~]# bash for1.sh
A
1
2
3
4
5
6
7
8
9
B
......

--- 4.解决换行问题 ---

[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
     A..D}
do
        echo -n $i
        for j in {
     1..9}
        do
                echo -n $j
        done
done

--- 5.测试脚本,观察结果 ---

[root@localhost ~]# bash for1.sh
A123456789B123456789C123456789D123456789

--- 6.外循环,添加一条空行语句 ---

[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
     A..D}
do
        echo -n $i
        for j in {
     1..9}
        do
                echo -n $j
        done
#空行
        echo 
done

--- 7.测试,完成预期 ---

[root@localhost ~]# bash for1.sh
A123456789
B123456789
C123456789
D123456789

--- 8.总结:循环嵌套的规则是:外部循环一次,内部循环全部。 ---

--- 9.需求:跳出关于5的循环需求 ---

A12346789
B12346789
C12346789
D12346789

--- 10.continue ---

[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
     A..D}
do
        echo -n $i
        for j in {
     1..9}
        do
                if [ $j -eq 5 ];then
                continue
                fi
                echo -n $j
        done
        echo 
done

--- 11.break ---
[root@localhost ~]# vim for1.sh
#!/bin/bash
for i in {
     A..D}
do
        echo -n $i
        for j in {
     1..9}
        do
                if [ $j -eq 5 ];then
                break 2
                fi
                echo -n $j
        done
        echo 
done

[root@localhost ~]# bash for1.sh
A1234

--- 12.shift ---.for循环不定义循环范围,循环去参数作为循环范围

[root@localhost ~]# vim sum.sh
#!/bin/bash
for i
do
        let sum+=$i
done
echo "sum : $sum"

[root@localhost ~]# bash sum.sh 
sum : 
[root@localhost ~]# bash sum.sh 1
sum : 1
[root@localhost ~]# bash sum.sh 2
sum : 2
[root@localhost ~]# bash sum.sh 3
sum : 3
[root@localhost ~]# bash sum.sh 1 3
sum : 4

Ⅱ.使用while循环,发现停不下来

[root@localhost ~]# vim sum-while.sh
#!/bin/bash
while [ $# -ne 0 ]
do
        let sum+=$1
        echo $sum
done
echo "sum : $sum"

[root@localhost ~]# bash sum-while.sh 1 2
-根本停不下来。因为循环为真。-.使用shift移动参数的命令,结果得以实现

[root@localhost ~]# vim sum-while.sh
#!/bin/bash
while [ $# -ne 0 ]
do
        let sum+=$1
        shift
done
echo "sum : $sum"

[root@localhost ~]# bash sum.sh 1 2
sum : 3
[root@localhost ~]# bash sum.sh 1 2 3
sum : 6
-shift 1使参数 左移1位,shift 2 左移2位-.另一个,创建用户的案例

[root@localhost ~]# vim useradd-shift.sh
#!/bin/bash
while [ $# -ne 0 ]
do
        useradd $1
        echo "$1 is created"
        shift
done

[root@localhost ~]# bash useradd-shift.sh aa bb
aa is created
bb is created

你可能感兴趣的:(Linux,Shell编程及自动化运维实现,shell,linux,运维)