我还没有接触 shell 函数的时候看到过一些类似编程语言的 shell 脚本,当时就感觉什么时候我也能写出这样的东西来就牛*了,接触过之后才知道,这个叫函数,很多数学不好的一听到函数也觉得算了,不学了,听着都难,按照人为的思路来理解一下就很简单了。
函数
shell 函数其实就是命令的集合,将代码模块化,也可以理解为是脚本的本中本。使用场景就是当你要多次执行一批命令时,将它编写为函数,就可以每次只调用函数名就可以,更加的规范的脚本的格式,省去很多重复的步骤,让脚本看起来高大上。
使用函数可以解决的问题
单个脚本代码量大
阅读脚本费时费力
排错困难
函数的优点
调用方便,节省内存
减少代码量,排错简单
改变代码顺序简单
语法结构
两种格式,一目了然,带小括号可以省去function,带 function 的可以省去小括号。
# 格式1
函数名() {
命令
}
# 格式2
function 函数名 {
命令
}
函数中的 return
函数中的 return 类似 shell 语句中的 exit,区别是 exit 会退出整个脚本,而 return 只是退出当前函数,继续执行函数以外的命令。
如果函数中 return 下面还有命令,则不会继续执行
示例
直接执行函数名即可调用执行函数
test() {
echo "hello world"
return 1
}
test && echo $?
return 的状态码也可以通过 $?
看到
函数传参
在函数中调用位置变量
test() {
echo "$1"
}
test "hello world"
在函数中调用函数本身,也叫函数递归调用,这样会不断生成新进程,然后导致系统奔溃停止脚本,递归函数和死循环一样,使用时多注意,了解一下即可。
test() {
echo "$1"
test "hello world"
}
test
数组
数组可以让用户一次赋予多个值,需要读取数据时只需通过索引调用就可以方便读出了。
普通数组:只能使用整数作为数组索引
关联数组:可以使用字符串作为数组的索引
普通数组
语法结构
数组名也叫变量名,数组中的值叫元素,元素之间以空格隔开,
变量名=(元素1 元素2 ...)
索引
索引代表每个元素所在的位置,起始索引为0,索引0表示数组中的第一位,依次类推
version=(v1 v2 v3)
索引号: 0 1 2
赋值方式
直接赋值
version=(v1 v2 v3 v4 v5)
version=($(cat /etc/passwd))
version=(mupei feiyi "FeiYi Blog")
索引赋值
version[0]="v1"
version[1]="v2"
version[1]="v3"
取值方式
取值方式:${数组名[索引号]}
version=(v1 v2 v3 v4 v5)
echo ${version[0]}
echo ${version[1]}
echo ${version[2]}
有几个特殊的取值操作
# 索引号使用 * 和 @ 可以获取数组中的所有元素
echo ${version[*]}
echo ${version[@]}
# 获取数组中的元素个数
echo ${#version[@]}
# 获取数组元素的索引号
echo ${!version[*]}
# 访问指定的连续元素,:3表示从索引号为3的元素开始,:2表示从1开始之后共2个元素
echo ${version[@]:3:2}
关联数组
申明关联数组
关联数组在使用之前要先申明该数组为关联数组,申明方式:declare -A 数组名
语法结构
declare -A 数组名
数组名=([字符串索引1]="元素1" [字符串索引2]="元素2" ...)
赋值方式
直接赋值
# 方式一
declare -A message
message=([name]="FeiYi" [age]="24" [sex]="man")
# 方式二
declare -A message=([name]="FeiYi" [age]="24" [sex]="man")
索引赋值
declare -A message
message[name]="FeiYi"
message[age]="24"
message[sex]="man"
取值方式
与普通数组一致
# 获取指定索引元素
echo ${message[name]}
echo ${message[age]}
# 获取所有元素
echo ${message[*]}
echo ${message[@]}
# 获取所有元素索引
echo ${!message[@]}
# 获取元素个数
echo ${#message[*]}