一、循环语句
1、for
结构
读取不同变量值,用来逐个执行同一组命令
2、while
3、until
二、Shell函数
作用:避免代码重复 还能将大工程量的代码分割成多个小的代码模块 方便调用 使代码更简洁 可读性更强
定义函数:
function 函数名 {
命令序列
....
}
函数名() {
命令序列
....
}
调用函数:直接在主代码中使用 函数名 即可调用函数定义的代码
获取函数的返回值
1)在函数里使用 echo 返回值,在函数外使用 变量=$(函数名) 获取返回值
2)在函数里使用 return 返回值,在函数外紧接着使用 echo $? 获取返回值(只能返回0-255范围的数值,超出部分为除以255取余数)
函数的传参
通过在 调用函数时,后面跟位置参数;在函数体里使用 $1 $2 来引用函数后面跟的位置参数
注意点:
1)函数体外的 $1 $2 代表的是执行脚本时,脚本后面跟的 第一个 第二个 位置参数
$# 参数个数
$@ $* 所有参数
2)函数体里面的 $1 $2 代表的是调用函数时,函数名后面跟的 第一个 第二个 位置参数
$# 参数个数
$@ $* 所有参数
3)不管在函数体内还是函数体外,$0 都代表脚本本身
函数变量的作用范围
脚本中定义的函数只能在脚本的shell环境有效
脚本中定义的变量默认是在脚本的shell环境中全局有效(即在函数体内外都有效)
在函数体内使用 local 变量 定义的局部变量只能在函数体内有效,且此后此局部变量与函数体外同名的全局变量没有任何关系
函数递归(在函数体里调用函数本身)
1)求阶乘
fact() {
if [ $1 -eq 1 ];then
echo 1
else
tmp=$[$1 - 1]
result=$(fact $tmp)
echo $[$1 * $result]
fi
}
2)递归目录
dgdir() {
for i in $(ls $1)
do
if [ -d $1/$i ];then
echo -e "$2$1/$i 为目录"
dgdir $1/$i "\t$2"
else
echo -e "$2$1/$i 为文件"
fi
done
}
函数库
先将一些常用的函数事先保存在一个特定的函数库文件中,需要使用时可直接在shell脚本文件开头位置用 source 函数库文件 加载函数即可直接使用。
vim myfunc.sh
hanshu1() {....}
hanshu2() {....}
vim shell.sh
source myfunc.sh #加载函数库文件
hanshu1 #直接调用函数
三、Shell数组
数组的元素可使用的数据类型:数值 或 "字符串" '字符串'
定义数组
数组名=(元素1 元素2 元素3 ....)
数组名[0]=元素1
数组名[1]=元素2
数组名[2]=元素3
....
list="元素1 元素2 元素3 ...."
数组名=($list)
查看数组的元素列表
echo ${数组名[@]}
echo ${数组名[*]}
查看数组的长度(元素的个数)
echo ${#数组名[@]}
echo ${#数组名[*]}
查看数组的元素下标
echo ${!数组名[@]}
echo ${!数组名[*]}
查看某个下标的元素值
echo ${数组名[下标]}
数组分片
echo ${数组名[@]:下标:长度}
echo ${数组名[*]:下标:长度}
数组字符替换
echo ${数组名[@]/旧字符/新字符}
数组名=(${数组名[*]/旧字符/新字符}) #通过重新定义的方式实现永久替换
数组删除
unset 数组名[下标] #删除数组的某个下标
unset 数组名 #删除数组
数组遍历和重新定义
arr=(1 2 3 4 5)
n=0
for i in ${arr[@]}
do
arr[$n]=$[i*2]
let n++
done
数组追加元素
数组名[新下标]=新元素
数组名[数组长度]=新元素 #仅适用于完整的数组
数组名+=(新元素1 新元素2 ....)
数组名=("${数组名[@]}" 新元素1 新元素2 ....)
向函数传数组参数
函数名() {
数组2=($@) #在函数体内将传入的列表重新组成数组
....
}
函数名 ${数组1[@]} #在函数体外将数组分解成列表传入
从函数返回数组
函数名(){
....
echo ${数组2[@]} #在函数体内以列表形式返回值
}
数组1=(函数名 参数) #在函数体外将函数执行的结果重新组合成数组