shell脚本之 函数——【初学者必看】

一、shell函数定义

  • 将命令序列按格式写在一起
  • 可方便使用命令序列
格式1:
function 函数名 {
    
    

命令序列
【return x】 //使用return或exit可以显示地结束函数

}
函数名
格式2:
函数名 () {
    
    

命令序列

}
函数名

经典案例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
#调用函数,是从上往下依次执行的

f1 (){
    
    
 echo hello
}
f3 (){
    
    
 echo "$(f1) $(f2)"
}

f2 (){
    
    
echo world
}
f3

在这里插入图片描述

1.1函数注意事项

1.直接写函数中调用

2函数直接写函数名同名函数后一个生效

3.调用函数一定要先定义

4.只要先定义了调用的其他函数定义顺序无关

1.2 函数返回值

return表示退出函数并返回一个退出值,脚本中可以用 $ ? 变量显示该值

使用原则:

  • 1、函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
  • 2、退出状态码必须是0~255,超出时值将为除以256取余

案例1:通过return返回一个乘积
在这里插入图片描述
在这里插入图片描述
案例2:求和
在这里插入图片描述
在这里插入图片描述

1.3函数调用的方法

示例1:

#!/bin/bash
h () {
    
    
echo "hello"
}
 
w () {
    
    
echo "world"
}
 
nihao () {
    
    
h
w
}
 
h
w
nihao

在这里插入图片描述
示例2:

#定义函数
#!/bin/bash
 
os (){
    
    
if  grep -i -q "CentOS Linux 7 " /etc/os-release
then 
 echo "此操作系统是centos 7"
 
 
elif  grep -i -q "CentOS Linux 6 " /etc/os-release
then 
 echo "此操作系统是centos 6"
 
elif  grep -i -q "CentOS Linux 8 " /etc/os-release
then 
 echo "此操作系统是centos 8"
fi
}
 
#调用函数
os

在这里插入图片描述

1.4 函数的传参

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…即使用位置参数来实现参数传递。

示例1:通过位置变量进行求和

#!/bin/bash
add () {
    
    
let sum=$1+$2
echo $sum
}
sum $1 $2

在这里插入图片描述
在这里插入图片描述

1.5 函数的作用范围

  • 函数在shell脚本中仅在当前shell环境中有效
  • shell脚本中变量默认全局有效
  • 将变量限定在函数内部使用local命令

注:
- 函数内部变量通过local来实现
- 通过定义myfun函数,再其内部设置局部变量i
- 函数内部和外部分别赋值,进行结果验证

案例:局部变量与全局变量区别

Local定义变量只能在内部使用6是局部的,8是全局的,用来指定变量

#!/bin/bash
myfun(){
    
    
local i 
i=6

echo $i
}
i=8

myfun
echo $i

在这里插入图片描述
在这里插入图片描述
但是注意了如果没有local i这句话时i是全局变量,当他为全局变量的时候,他是从上往下执行的,系统只承认第一个定义的i的值,以后所有的i不管在定义为什么都是第一个定义的值。
在这里插入图片描述
当没有local i 这句话时,代表他是一个全局。
在这里插入图片描述

1.6函数的参数

1.6.1参数的用法

函数名称 参数1 参数2 参数3…

1.6.2参数的表示方法

  • $1 2...... 2 ...... 2......${10} ${11}

1.6.3 经典案例:

1.6.3.1 求前一个数与后一个数相乘的结果

#!/bin/bash
jiecheng (){
    
    
zhangzhihan=1
for i in {
    
    1..6}
do
let zhangzhihan=$i*$zhangzhihan
echo $zhangzhihan
done
}
jiecheng

在这里插入图片描述在这里插入图片描述

1.6.3.2 求1到6的阶乘【注意done的位置】

#!/bin/bash
#求阶乘16的阶乘
jiecheng (){
    
    
zhangzhihan=1
for i in {
    
    1..6}
do
let zhangzhihan=$i*$zhangzhihan
echo $zhangzhihan
done
}
jiecheng

在这里插入图片描述
在这里插入图片描述

1.6.3.3 判断是否为文件

#!/bin/bash
file=/home/error.txt
zzh6(){
    
    
if [ -f $file ];then  #判断是否为文件
  return 80
else
  return 40
fi

}
zzh6
echo $?

在这里插入图片描述
在这里插入图片描述

1.7 递归函数

  • 调用自己本身的函数

1.7.1 小福袋:

给命令行提示字符加颜色
PS1="\[\e[1;34m\][\u@\h \W]\\$\[\e[0m\] "

PS1="\[\e[1;35m\][\[\e[1;34m\]\u\[\e[1;36m\]@\[\e[1;34m\]\h \[\e[1;31m\]\w\[\e[1;35m\]]\[\e[1;36m\]\\$\[\e[0m\] "

\[\e[1;35m\][ ====> 定义左边的"["
\[\e[1;34m\]\u ====> 定义用户名
\[\e[1;36m\]@ ====> 定义"@"
\[\e[1;34m\]\h ====> 定义第一个点(.)之前的主机名 //34代表文件
\[\e[1;31m]\w ====> 定义目录完整路径
\[\e[1;35m]] ====> 定义"]"
\[\e[1;36m\]\\$ ====> 定义"#""$"
\[\e[0m\] ====> 一段不显示字串的结束

1.7.2 经典案例

1.7.2.1 递归显示var下的log里面有哪些是目录

如果是目录就显示为蓝色判断目录下,有哪些目录,打印显示出,不显示文件

[root@localhost ~]# vim zzh7.sh 
#!/bin/bash
#列出目录文件的列表,目录可用颜色表示(蓝色表示目录;白色表示文件)文件显示层及关系
list (){
    
    
for i in $1/*  #$1下面的所有内容
do
   if [ -d $i ];then   #-d代表是目录 只要是目录的我就用蓝色显示
   echo -e "\e[34m$i\e[0m"
#标准格式【】里面的内容是表示颜色  -e表示转义字符标识
   echo $i
   list $i " $2"
   else
   echo "$2$i"
   fi
done
}
list $1 $2 #调用变量

在这里插入图片描述
在这里插入图片描述

1.7.2.2 交互式 递归方式计算你输入的数值作为阶乘

#!/bin/bash
#交互式 递归方式计算你输入的数值作为阶乘
#比如我第一次输入5
fun (){
    
    
if [ $1 -eq 1 ];then
   echo 1
else
#5不等于1执行else的 此时tp=5-1=4;res=4 此时echo为5*4
  local tp=$[ $1 - 1 ]  #这个是局部  
  res=$(fun $tp)  #相当于直接调用tp本身
  echo $[ $1 * $res ] #$15
fi
}

read -p "请输入:" num
res=$(fun $num)
echo $res


#执行过程
#fun 5 $1=5 tp=4 res=fun 4 echo 5 * 4()      5*4*3*2*1
#fun 4 $1=4 tp=3 res=fun 3 echo 4 *3(fun)    4*3*2*1
#fun 3 $1=3 tp=2 res=fun 2 echo 3 * 2(fun)   3*2*1
#fun 2 $1=2 tp=1 res=fun 1 echo 2*1(fun)     2*1
#fun 1 $1  echo 1                            1  

在这里插入图片描述
在这里插入图片描述

二. 数组

2.1 shell数组的定义

  • 数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组)
  • 数组元素的下标由 0 开始
  • Shell 数组用括号来表示,元素用"空格"符号分割开
  • 在shell语句中,使用、遍历数组的时候,数组格式要写成 ${arr[@]} 或 ${arr[*]}

数组是存放相同类型数据的集合,在内存中开辟了连续的空间,通常配合循环使用哦!

2.2 数组的分类

普通数组:不需要声明直接定义,下标索引只能是整数
关联数组:需要用declare -A 声明否则系统不识别,索引可以是字符串

2.3 数组的定义方式

2.3.1 方式一

1.直接把要加入数组的元素用小括号括起来,中间用空格分开

num=(11 22 33 44

在这里插入图片描述

2.3.2 方式二

2.精确的给每一个下标索引定义一个值加入数组,索引数字可以不连续

num=([0]=55 [1]=66 [2]=77 [3]=88)

在这里插入图片描述

2.3.3 方式三

先把要加入数组的元素全部先赋值给一个变量,然后引用这个变量加入到数组

list=11 12 13 14”
num=($list)

在这里插入图片描述

2.3.4 方式四

可以把命令的结果用小括号括起来添加到数组,那么数组会以空格或者制表符区分每一个元素

num=(`cat /etc/passwd`)
[root@localhost ~]# echo ${
    
    #num[*]}
111
[root@localhost ~]# echo ${
    
    num[0]}
root:x:0:0:root:/root:/bin/bash
注意以下特殊方式:
[root@localhost ~]# list[0]=1    //没有定义数组之前也可这样直接定义元素
[root@localhost ~]# 
[root@localhost ~]# echo ${
    
    list[*]}
1

[root@localhost ~]# list=([0]=1 [1]=2 [3]=4)    //定义数组时所以可以是不连续的
[root@localhost ~]# echo ${
    
    list[*]}
1 2 4
[root@localhost ~]# echo ${
    
    !list[*]}       //没有2这个索引,数组元素为3
0 1 3


[root@localhost ~]# ff=(1 2 zhangsan lisi)    //不是同一数据类型的也可定义为一个数组
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# echo ${
    
    ff[*]}
1 2 zhangsan lisi

2.4数组格式

如:arr=(11 22 33 44)
数组名称:arr
数组元素:11,12,12,14,数组元素默认是以空格分隔的
数组长度:4,有4个元素
数组下标:每个数组元素都有一个下标索引,一般从0开始,33是数组第三个元素,但是它的下标索引是2

2.4.1 数组的常用操作 以及 经典案例

2.4.1.1 读取数组和元素

[root@localhost ~]# fruit=(apple banana orange)   //定义了一个水果的数组
[root@localhost ~]# echo ${
    
    #fruit[*]}       //查看这个数组元素的个数,也是数组长度
3
[root@localhost ~]# echo ${
    
    !fruit[*]}         //查看这个数组元素的索引
0 1 2
[root@localhost ~]# echo ${
    
    fruit[*]}          //查看这个数组的元素
apple banana orange
[root@localhost ~]# echo ${
    
    fruit[@]}        //查看这个数组的元素
apple banana orange
[root@localhost ~]# echo ${
    
    fruit[0]}         //查看这个数组索引为0的元素
apple

[root@localhost ~]# declare -a | grep fruit      //查看声明的所有变量可以看到数组
declare -a fruit='([0]="apple" [1]="banana" [2]="orange")'

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4.1.2 元素切片

[root@localhost ~]# arr=(1 2 3 4 5 6 7 8)
[root@localhost ~]# echo ${
    
    arr[*]:2:3}     //提取从索引2开始的3个元素
3 4 5
[root@localhost ~]# echo ${
    
    arr[*]:2:2}     //提取从2开始的2个元素
3 4
[root@localhost ~]# echo ${
    
    arr[*]:0:2}
1 2

在这里插入图片描述

2.4.1.3 数组的遍历

#!/bin/bash
a=(1 2 3 4 5 6)
for i in ${
    
    a[@]}
do
   echo $i
done

在这里插入图片描述
在这里插入图片描述

2.4.1.4 定义某一个元素

[root@localhost ~]# fruit[0]=pear
[root@localhost ~]#
[root@localhost ~]# echo ${
    
    fruit[*]}
pear banana orange

2.4.1.5元素替换

定义或替换某一个元素
[root@localhost ~]# fruit[0]=pear
[root@localhost ~]#
[root@localhost ~]# echo ${
    
    fruit[*]}
pear banana orange

[root@localhost ~]# echo ${
    
    fruit[*]/banana/ba}   //临时替换
pear ba orange
[root@localhost ~]# echo ${
    
    fruit[*]}
pear banana orange

2.4.1.6 元素删除

[root@localhost ~]# unset fruit[0]
[root@localhost ~]#
[root@localhost ~]# declare -a | grep fruit
declare -a fruit=‘([1]=“banana” [2]=“orange”)’

2.4.1.7 数组删除和指定下标的值删除

[root@localhost ~]# unset arr

在这里插入图片描述
在这里插入图片描述

2.4.1.8 数组追加元素

法一 :直接使用下标进行元素的追加

数组名[下标]=变量
[root@localhost ~]# a=(10 20 30 40)
[root@localhost ~]# echo ${
    
    a[*]}
10 20 30 40
[root@localhost ~]# a[4]=50
[root@localhost ~]# echo ${
    
    a[*]}
10 20 30 40 50
[root@localhost ~]# a[5]=60
[root@localhost ~]# echo ${
    
    a[*]}
10 20 30 40 50 60

在这里插入图片描述
法二:将数组的长度作为下标进行追加元素

数组名[${
    
    数组名[@]}]=变量名

在这里插入图片描述
法三:使用+=进行追加

数组名+=(变量1 变量2 ...)

在这里插入图片描述

2.4.1.9 查看所有数组—declare -a

在这里插入图片描述

2.5 获取数组下标对应的值:

数组名=(元素0  元素1  元素2  ……)					定义数组
echo ${
    
    数组名[索引值]}							输出数组索引值对应的元素,索引值为从0开始

在这里插入图片描述

2.6 冒泡排序

每次对比,确定最后一位【所以我数组长度需要-1】
#!/bin/bash
array=(90 70 82 100 30 66) #定义数组
echo "old_array:${array[*]}" #1.代表排序前的数组

lt=${
    
    #array[*]} #数组长度
#定义比较轮数,比较轮数为数组长度-1,从1开始
for ((i=1;i<=$lt;i++))
#当下标为0for ((i=0;i<$lt;i++))
do
   #确定比较元素的位置,比较相邻的两个元素,较大的数往后放,在比较次数谁比较轮数而减少
    for ((j=0;j<$lt-i;j++))
    do
        #定义第一个元素的值
       first=${
    
    array[$j]}
       #定义第二个元素的值
       k=$[$j+1]
       second=${
    
    array[$k]}
      #如果第一个元素比第二个元素大,就互换
      if [ $first -gt $second ];then
      #把第一个元素的值保存到临时变量中
       temp=$first
     #把第二个元素赋值给第一个元素
       array[$j]=$second
     #把临时变量赋值给第二个元素
       array[$k]=$temp
   fi
    done
done
echo "new_array:${array[*]}"

在这里插入图片描述
在这里插入图片描述

喜欢小编记得点个小星星哦!

猜你喜欢

转载自blog.csdn.net/weixin_59663288/article/details/124478809
今日推荐