SHELL-函数 & 数组
(1)函数
一 函数介绍
# 什么是函数?
具备某一功能的工具=》函数
事先准备工具的过程=》函数的定义
遇到应用场景拿来就用=》函数的调用
# 为何要用函数?
没有引入函数前,遇到重复使用某一个功能的地方,只能复制黏贴实现该功能的代码,这会导致
1、代码冗余=》程序组织结构不清晰,可读性差
2、如果该功能的代码需要修改,那么需要找到所有黏贴这段代码的地方进行修改=》可扩展性差
# 如何用函数?
函数的使用应该遵循一个原则:先定义、再调用
二 函数的基本使用
1、先定义
# 格式1: 推荐
function 函数的名字() {
命令1
命令2
命令3
...
}
# 格式2
function 函数的名字 {
命令1
命令2
命令3
...
}
# 格式3
函数的名字() {
命令1
命令2
命令3
...
}
2、后调用
函数的名字
示例
[root@egon day06]# ./1.sh
函数f1调用了
函数f2调用了
函数f3调用了
[root@egon day06]# cat 1.sh
#!/bin/bash
function f1() {
echo '函数f1调用了'
}
function f2 {
echo '函数f2调用了'
}
f3() {
echo '函数f3调用了'
}
f1
f2
f3
[root@egon day06]# ./1.sh
函数f1调用了
函数f2调用了
函数f3调用了
[root@egon day06]#
三 函数的参数
可以把函数想象成一座工厂
函数=》工厂
函数体代码=》流水线
调用者为函数传递的参数=》为工厂运送的原材料
函数的返回值=》流水线加工的产品
ps
函数是否需要参数,取决于函数体代码是否需要
示例
#!/bin/bash
function add() {
# [ $# -ne 2 ] && echo "必须为函数传入两个参数" && exit
[ $# -ne 2 ] && echo "必须为函数传入两个参数" && return
res=$[ $1 + $2 ]
echo "10+11=$res"
}
add 10 11 22
echo "=============>"
四 函数的返回值
在shell语言中return返回的是函数运行的状态,而且只能返回值int型(0-255)
return是函数结束的标志,函数内可以有多个return,但只要执行一次,整个函数就立即结束,并且将return后的当做函数的运行状态返回
#!/bin/bash
function test() {
echo "hello"
return 0
echo "world"
return 255
echo "hahaha"
return 256
}
test
echo $?
ps:如果函数体代码没有return,那么函数的运行状态默认就是函数体代码最后一条命令的运行状态
五 作用域
#1 什么是作用域
作用域即作用域范围,具体是值变量的作用域范围
何为变量的作用域范围:定义一个变量,都可以在什么地方访问到
#2 为何要有作用域
为了区分变量查找范围的优先级,避免冲突
1、局部作用域=》函数内用local关键字声明的变量=》只能在函数内访问
#!/bin/bash
function f1() {
local x=111
echo $x # 在函数内找
}
f1
echo $x # 在函数外找
2、全局作用域=》在当前进程内声明的变量=》可以在当前进程的任意位置访问到
#!/bin/bash
y=222 # 全局变量
function f2() {
echo $y
}
f2
echo $y
ps:只要没有被local声明的变量,都是全局变量,都是在整个进程有效
#!/bin/bash
function f2() {
z=333
echo $z
}
f2
echo $z
3、环境变量
export声明的变量称之为环境变量,环境变量的范围:父进程定义的环境变量,子子孙孙进程都可以看到
注意:
1、传子不传爹
2、没有父子关系export无效
4、登录shell与非登陆shell
(2)数组
一 数组介绍
#1、数组
一组数据的集合,与整型、浮点型、字符串型不同的是一个数组可以同时存放多个值
#2、为何要用数组
把相关的变量归置到一起,程序的组织结构更清晰
#3、如何用数组
二 数组的使用
1、定义
# 方式一
array=(1.3 111 "aa")
# 方式二
array=([0]=1.3 [1]=111 [2]="aaa")
ps: 可以换顺序,也可空着来
array=([2]="aaa" [0]=1111111)
# 方式三
[root@egon ~]# array[0]=1.3
[root@egon ~]# array[2]="aaa"
# 方式四:
[root@egon ~]# array=(`ls .`)
[root@egon ~]# echo ${array[0]}
anaconda-ks.cfg
[root@egon ~]# echo ${array[1]}
check_httpd.sh
[root@egon ~]# echo ${array[2]}
2、使用
array=(1.3 111 "aa")
# 1、查看数组元素
echo ${array[0]}
echo ${array[-1]}
echo ${array[*]} # 查看数组内所有元素
echo ${array[@]} # 查看数组内所有元素
echo ${#array[*]} # 查看数组内元素的个数
4
[root@tcy ~]# declare -a # 查看声明过的数组
# 2、修改和添加
array[0]=3.6
array[5]=3333
# 3、删除
删除整个数组
unset array
删除某一个
[root@tcy ~]# array=(1.3 111 "aa")
[root@tcy ~]# echo ${array[*]}
1.3 111 aa
[root@tcy ~]#
[root@tcy ~]# unset array[1]
[root@tcy ~]# echo ${array[*]}
1.3 aa
[root@tcy ~]#
# 4、截取(了解)
指定索引截取
[root@tcy ~]# array=(tcy 18 male IT 1.80 11 22 33)
[root@tcy ~]# echo ${array[*]:3:2}
IT 1.80
指定元素删除(不改变原数组)
array=(one two three four five fire)
echo ${array[*]#one}
echo ${array[*]#five}
echo ${array[*]#f*e}
# 5、替换(了解)
[root@tcy ~]# array=(one two three four five fire)
[root@tcy ~]# echo ${array[*]/f*e/111}
one two three four 111 111
三 关联数组
上面介绍的索引对应元素的数组称之为普通数组
关联数组指的是可以指定key对应value
[root@ ~]# declare -A array=(["name"]="tcy" ["age"]=18 ["gender"]="male")
[root@tcy ~]# echo ${array["age"]}
18
[root@tcy ~]# echo ${array[*]}
male tcy 18
[root@tcy ~]# echo ${array[@]}
male tcy 18
[root@tcy ~]# echo ${#array[@]}
3
[root@tcy ~]#
四 数组的遍历
遍历普通数组的方式1:取值
array=(one two three four five fire)
for i in ${array[*]}
do
echo $i
done
遍历普通数组的方式2:取索引,进而取值
array=(one two three four five fire)
for i in ${!array[*]}
do
echo $i ${array[$i]} # 获取索引及其对应的元素
done
遍历关联数组的方式1: 取值
declare -A array=(["name"]="egon" ["age"]=18 ["gender"]="male")
for x in ${array[*]}
do
echo $x
done
遍历关联数组的方式2: 取key,进而取value
declare -A array=(["name"]="egon" ["age"]=18 ["gender"]="male")
for k in ${!array[*]}
do
echo $k ${array[$k]}
done
练习:基于关联数组统计/etc/passwd文件中不同种类shell的个数
[root@egon day06]# cat 11.sh
#!/bin/bash
declare -A shell_count
while read line
do
s=`echo $line|awk -F: '{print $7}'`
let shell_count[$s]++
done < /etc/passwd
for k in ${!shell_count[*]}
do
echo $k ${shell_count[$k]}
done
[root@egon day06]# ./11.sh
/sbin/nologin 21
/bin/sync 1
/bin/bash 2
/sbin/shutdown 1
/sbin/halt 1
[root@egon day06]#