一、函数
语句块定义成函数约等于别名
函数使用方法:
- 定义函数
- 再引用函数
1.1基本格式
1)function 函数名{
命令序列
}
2)函数名(){
命令序列
}
3)function func_name () {
...函数体...
}
注意事项
- 直接写 函数中调用函数 直接写函数名
- 同名函数 后一个生效
- 调用函数一定要先定义
- 每个函数是独立
[root@hzw ~]# func1 (){ hostname;date; }
[root@hzw ~]# func1
xkj
2024年 05月 14日 星期二 16:06:46 CST
1.2查看函数
[root@hzw ~]# declare -F
#函数列表
declare -f __HOSTNAME
declare -f __SIZE
declare -f __SLAVEURL
declare -f __VOLNAME
declare -f __expand_tilde_by_ref
declare -f __get_cword_at_cursor_by_ref
判断操作系统版本:
[root@hzw ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
1.3删除函数
命令:unset func_name
[root@hzw ~]# unset func1
[root@hzw ~]# declare -F |grep func1
[root@hzw ~]# declare -F |grep func1 |wc -l
0
1.4 函数的返回值
函数可以通过return语句设置返回值。
return 从函数中返回,用最后状态命令决定返回值 return 0 无错误返回 return 1-255 有错误返回
超过256的值,会和256相除取余数
返回值的作用:
- 对函数执行的结果进行判断和处理:函数可以返回不同的值来表示不同的执行状态或错误情况。
- 传递函数执行的结果给其他部分:函数的返回值可以被赋值给变量,能将函数的计算结果传递给其他命令或者再次使用。
- 作为脚本的退出状态码:根据不同的返回值来设置不同的退出状态码。
1.5 函数的传参数
test() {
echo "Parameter 1: $1"
echo "Parameter 2: $2"
}
test $1 $2
.......注释.........................................................
test1 $1 $2
# 这两个位置变量 是脚本的位置变量,就是执行脚本时,输入的值
test1 () {
}
#test1函数中的位置变量和脚本的位置变量相对独立
#如果 变成
#test1 $2 $1
#那么 对于test1函数来说,函数的$1就是脚本的$2
1.6函数文件
将函数代码写入一个脚本文件,在需要的时候调用该脚本文件,相当于直接调用函数。 在Shell脚本中使用函数文件时,需要写上函数文件的绝对路径。
1.7 递归函数(重要)
递归归函数是指在函数体内调用自身的函数,用于需要重复执行相同或类似任务的场景。 编写递归函数时要确保设定递归的结束条件,以避免死循环。
#简单的示例#
#!/bin/bash
# 定义递归函数
factorial() {
if (( $1 <= 1 )); then
echo 1
else
local prev=$(factorial $(( $1 - 1 )))
echo $(( $1 * $prev ))
fi
}
# 调用递归函数
read -p "输入一个正整数: " n
result=$(factorial $n)
echo "阶乘结果为: $result"
1.8 函数练习
1.8.1判断系统类型,安装httpd服务
#!/bin/bash
os () {
if grep -qi 'centos' /etc/os-release
then
echo "centos"
elif grep -qi 'ubunto' /etc/os-release
then
echo "ubuntu"
else
echo "不支持此系统"
fi
}
#调用函数
os
if [ `os` = centos ]
then
yum install -y httpd
elif [ `os` = ubuntu ]
then
apt install apache2 -y
else
echo " fail "
fi
-
[root@hzw ~]# bash xit.sh centos 已加载插件:fastestmirror, langpacks base | 3.6 kB 00:00 extras | 2.9 kB 00:00 updates | 2.9 kB 00:00 Loading mirror speeds from cached hostfile * base: mirrors.ustc.edu.cn * extras: mirrors.ustc.edu.cn * updates: mirrors.ustc.edu.cn 正在解决依赖关系 --> 正在检查事务
1.8.2 用递归函数计算正整数的阶乘
```bash
#交互式
#!/bin/bash
read -p "请输入一个数:" num
fact() {
local n=$1
if [ $n -eq 0 ]; then
echo 1
elif [ $n -eq 1 ]; then
echo 1
else
local x=$[$n-1]
local result=$(fact $x)
echo $[$n * $result]
fi
}
result=$(fact $num)
echo "阶乘结果为:$result"
[root@xkj ~]# bash jc.sh
请输入一个数:8
阶乘结果为:40320
二、数组
2.1数组的分类
2.2.1 定义数组
1.一次赋值全部元素
数组名=( value0 value1 value2 value3 ......)
[root@hzw ~]# aa=(11 22 33 44)
[root@hzw ~]# echo ${aa[*]}
11 22 33 44
2.通过下标值定义每个元素
数组名=([0]=value [1]=value1 [2]=value2 ....) #[0] [1] [2] 为下标值
[root@hzw ~]# cc=([0]=1 [1]=2 [2]=3)
[root@hzw ~]# echo ${cc[0]}
1
[root@hzw ~]# echo ${cc[2]}
3.先定义列表,再引用列表的值定义数组
列表名="value0 value1 value2 value3 ...... "
数组名=($列表名)
[root@hzw ~]# xkj="a b c d e f"
[root@hzw ~]# x=($xkj)
[root@hzw ~]# echo ${x[*]}
a b c d e f
4.一次只赋值一个元素
数组名[0]="value1"
数组名[1]="value2"
数组名[2]="value3"
[root@hzw ~]# a1[0]="a"
[root@hzw ~]# a1[1]="b"
[root@hzw ~]# a1[2]="c"
[root@hzw ~]# echo ${a1[*]}
a b c
5.read -a交互式
read -a 数组名 要输入的内容 #数组内容
echo ${数组名[@]} #查看
[root@hzw ~]# read -a xx
12 23 34 45
[root@hzw ~]# echo ${xx[1]}
23
[root@hzw ~]# echo ${xx[@]}
12 23 34 45
[root@hzw ~]# echo ${#xx[@]}
4
下标值和索引值表示相同的意思,即元素在数组中的位置。 数组的下标值从0开始,逐个递增,用于唯一标识数组中的每个元素。
2.2普通数组和关联数组
2.2.1普通数组
-
使用连续的整数值作为索引,从0开始递增。
-
声明时使用
declare或declare -a命令。 -
元素之间的顺序是固定的,根据索引进行访问。
-
示例:
fruits=("apple" "banana" "cherry") echo ${fruits[0]} # 输出: apple echo ${fruits[1]} # 输出: banana
普通数组使用整数索引访问数组中的元素。
2.2.2关联数组
- 使用任意字符串作为键来访问和存储元素。
- 声明时使用
declare -A命令。 - 元素之间的顺序是不固定的,通过键进行访问。
- 示例:
declare -A ages
ages["Alice"]=25
ages["Bob"]=30
echo ${ages["Alice"]} # 输出: 25
echo ${ages["Bob"]} # 输出: 30
关联数组使用字符串键来标识和存储元素。
2.3 引用数组的值
1)获取数组长度(数组中所有元素的个数)
a=(1 2 3 4 5)
#定义数组
echo ${#a[*]}
#显示下标总个数 或 echo ${#a[@]}
#显示下标总个数
[root@hzw ~]# a=(1 2 3 4 5)
[root@hzw ~]# echo ${a[*]}
1 2 3 4 5
2)获取数组数据列表(所有元素的值)
[root@hzw ~]# a=(1 2 3 4 5)
[root@hzw ~]# echo ${a[*]}
1 2 3 4 5
3)查看数组内某一个元素
x=${a[2]}
[root@hzw ~]# x=${a[2]}
[root@hzw ~]# echo $x
3
4)读取下标的个数
[root@hzw ~]# echo ${!a[*]}
0 1 2 3 4
2.3数组删除
#删除数组中所有元素
#举个例子 a=(1 2 3 4 5) unset a echo ${a[*]}
[root@hzw ~]# unset a
[root@hzw ~]# echo ${a[*]}
#删除指定元素 #举个例子 a=(1 2 3 4 5) unset a[2] echo ${a[*]}
[root@hzw ~]# a=({1..10})
[root@hzw ~]# unset a[2]
[root@hzw ~]# echo ${a[*]}
1 2 4 5 6 7 8 9 10
2.4 数组替换
a=(1 2 3 4 5)
echo ${a[@]/4/66} #${数组名[@或*]/查找字符/替换字符}
echo ${a[@]} #并不会替换数组原有内容
a=(${a[@]/4/66}) #要实现改变原有数组,可通过重新赋值实现
echo ${a[@]}