一、函数
语句块定义成函数约等于别名
函数使用方法:
-
定义函数
-
再引用函数
1.1基本格式
1)function 函数名{
命令序列
}
2)函数名(){
命令序列
}
3)function func_name () {
...函数体...
}
注意事项</font>
-
直接写 函数中调用函数 直接写函数名
-
同名函数 后一个生效
-
调用函数一定要先定义
-
每个函数是独立
[root@xkj ~]# func1 (){ hostname;date; } [root@xkj ~]# func1 xkj 2024年 05月 14日 星期二 16:06:46 CST
1.2查看函数
[root@xkj ~]# 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@xkj ~]# 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@xkj ~]# unset func1 [root@xkj ~]# declare -F |grep func1 [root@xkj ~]# 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@xkj ~]# 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@xkj ~]# aa=(11 22 33 44) [root@xkj ~]# echo ${aa[*]} 11 22 33 44
2.通过下标值定义每个元素
数组名=([0]=value [1]=value1 [2]=value2 ....) #[0] [1] [2] 为下标值
[root@xkj ~]# cc=([0]=1 [1]=2 [2]=3) [root@xkj ~]# echo ${cc[0]} 1 [root@xkj ~]# echo ${cc[2]}
3.先定义列表,再引用列表的值定义数组
列表名="value0 value1 value2 value3 ...... "
数组名=($列表名)
[root@xkj ~]# xkj="a b c d e f" [root@xkj ~]# x=($xkj) [root@xkj ~]# echo ${x[*]} a b c d e f
4.一次只赋值一个元素
数组名[0]="value1"
数组名[1]="value2"
数组名[2]="value3"
[root@xkj ~]# a1[0]="a" [root@xkj ~]# a1[1]="b" [root@xkj ~]# a1[2]="c" [root@xkj ~]# echo ${a1[*]} a b c
5.read -a交互式
read -a 数组名 要输入的内容 #数组内容
echo ${数组名[@]} #查看
[root@xkj ~]# read -a xx 12 23 34 45 [root@xkj ~]# echo ${xx[1]} 23 [root@xkj ~]# echo ${xx[@]} 12 23 34 45 [root@xkj ~]# 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@xkj ~]# a=(1 2 3 4 5) [root@xkj ~]# echo ${a[*]} 1 2 3 4 5
2)获取数组数据列表(所有元素的值)
[root@xkj ~]# a=(1 2 3 4 5) [root@xkj ~]# echo ${a[*]} 1 2 3 4 5
3)查看数组内某一个元素
x=${a[2]}
[root@xkj ~]# x=${a[2]} [root@xkj ~]# echo $x 3
4)读取下标的个数
[root@xkj ~]# echo ${!a[*]} 0 1 2 3 4
2.3数组删除
#删除数组中所有元素
#举个例子 a=(1 2 3 4 5) unset a echo ${a[*]}
[root@xkj ~]# unset a [root@xkj ~]# echo ${a[*]}
#删除指定元素 #举个例子 a=(1 2 3 4 5) unset a[2] echo ${a[*]}
[root@xkj ~]# a=({1..10}) [root@xkj ~]# unset a[2] [root@xkj ~]# 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[@]}