shell函数和数组

一、函数

1.1、函数的定义(两种方式)

//1.这是一种规范写法

function 函数名 {
command
}      

//2.最常用因为最简洁
函数名(){    
command

函数定义完之后并不会自动执行,需要调用才行。 

1.2、 函数返回值

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

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

例子

#!/bin/bash
function fun1 {
read -p "请输入一个数字" num
echo "this is a function example"
return $[$num*2]
}
fun1
echo $?

1.3、函数的调用

1.直接在脚本里定义函数的代码块后写函数名即可完成调用

#!/bin/bash
function fun1 {  //注意 {前有空格
echo "this is a function example"
 }
fun1

注意①:函数名必须是唯一,
如果先定义了一个,再用同样的名称定义,第二个会覆盖第一个的功能,
出现了你不想要的结果,所以这里一定要注意不要重名!

注意②:调用函数之前必须先进行定义!
注意③:不一定要在脚本开头就定义函数,只要调用之前定义就可以

2.如果是在其他地方嵌套调用等情况,不可以直接写函数的值,避免无法识别,可以用反撇号引起来,相当于是调用函数的结果。

#!/bin/bash
f1 () {
echo hello
}
f2 () {
echo hi
}
f3 () {
echo "f1  $(f2) `f2` "
}

f3

1.5、函数的作用范围

在 Shell 脚本中函数的执行并不会开启一个新的子 Shell,而是仅在当前定义的 Shell 环境中有效。如果Shell脚本中的变量没有经过特殊设定,默认在整个脚本中都是有效的。在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令local来实现。函数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响。

  • shell脚本中变量默认全局有效
  • local命令:将变量限定在函数内部使用
#!/bin/bash
i=99
f1 () {
local i=8
echo $i
}
f2 () {
echo $i
}


f1
f2
echo $i

简答的说,local就是只有在代码块有效,局部的。

1.6、函数的参数

让调用函数时直接使用

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

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

这里相当于调用了脚本的参数了,然后把 脚本的位置变量  传递给函数进行计算 

1.6.1、案例:阶乘1

5的阶乘为1*2*3*4*5

#!/bin/bash
factorial() {
read -p "你要几的阶乘" m
csz=1
for((i=1;i<=$m;i++))
do
let  csz=csz*$i
done

}
factorial
echo "$csz"

1.7、函数的递归

函数自己调用自己的本身
列出目录内文件列表,目录用蓝色表示,文件显示层级关系

显示二级目录

#!/bin/bash
list(){
for i in $1/*
do
        if [ -d $i ];then
        echo -e "\e[34m$i\e[0m"
        list $i " $2"
        else
        echo "$2$i"
fi
done
}
list $1 $2

1.7.1、案例:阶乘2

#!/bin/bash
fa () {
if  [  $1 -eq 1  ]
then
echo 1
else
 local tp=$[$1 - 1]
 local res=$(fa $tp)
 echo $[ $1 * $res ]
fi

}
fa 5

二、数组的定义

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

数组的分类

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

数组包括的数据类型
数值类型
字符类型:
使用“ ” 或 ‘ ’ 定义
 

2.1、数组的三种定义方式

  • 第一种:直接把要加入数组的元素用小括号括起来,中间用空格分开

格式

数组名= (value0 value1 value2)

num=(11 22 33 44)
${#num} 显示字符串长度
 

  • 第二种:精确的给每一个下标索引定义一个值加入数组,索引数字可以不连续

数组名=([0]=value [1] =value  [2] =value...)

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

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

格式

列表名="value0 value1 value2....”
数组名=($列表名) 

第一种的变形

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

  • 第四种:根据下标定义

数组名[0]="value"
数组名[1]="value"
数组名[2]="value"

数组名[0]=“11”
数组名[0]=“22”
数组名[0]=“33”

2.2、获取数组的长度 、数据

arr_number=(10 20 30 40 50)
arr_length=${#arr_number[*]}
                   ${#arr_number[@]}

echo $arr_length

不加#就是获取数据列表

 下标从0开始

2.3、数组元素遍历

#!/bin/bash
arr=(10,20,30,40)
for i in ${arr[*]}
do
echo $i
done

2.4、元素切片 

#!/bin/bash
arr=(10 20 3 4 5 6 7 8)
echo ${arr[*]:2:3}     #提取从索引2开始的3个元素

echo ${arr[@]:2:2}      

echo ${arr[*]:0:2}

2.5、数组(元素)替换

/查找字符/替换字符

并不会替换数组原有内容

#!/bin/bash
arrr=(10,20,10,40)
echo ${arrr[@]/10/2}
echo ${arrr[@]/2/5}
echo ${arrr[@]/0/1}

2.7、数组删除

删除数组

unset arr 

指定删除  

删除第四个元素

unset arr[4]

2.8、数组排序算法:冒泡排序

方法一

#!/bin/bash
num=(90 70 60 40 50 30)
for ((i=0;i<${#num[*]};i++))
  do
    for ((j=i+1;j<${#num[*]};j++))
     do
      if [ ${num[$i]} -gt ${num[$j]} ]
      then
       temp=${num[$i]}
       num[$i]=${num[$j]}
       num[$j]=$temp
      fi
     done
  done
echo ${num[*]

方法二

#!/bin/bash
#存入元素
#set -x
k=0
while true
do
read -p "是否存入元素:" doing
if [ $doing == "no" ];then
break
fi
read -p "请输入第$[$k+1]个元素:" key
score[$k]=$key
let k++
done
#外层为轮
for ((i=1;i<${#score[*]};i++));do
#内层为次
  for ((j=0;j<${#score[*]}-i ;j++));do
#两数交换
    if [ ${score[$j]} -gt ${score[ `expr $j + 1`]} ];then
    tmp=${score[`expr $j + 1`]}
    score[ `expr $j + 1` ]=${score[$j]}
    score[$j]=$tmp
    fi
  done
done
echo ${score[*]

方法三

#定义一个初始数组
arr=(30 10 50 60 40 20)
echo “原数组的顺序为: ${arr[@]}"
#获取数组的长度
length=${#arr[@]}
#冒泡排序:
#定义比较轮数,为数组长度减一,并且要从1开始
for ( (i=1; i<$length; i++))
do
#确定每次比较的元素下标,比较相邻2个元素,大的往后放,小的往前放,并且每轮比较的次数要随着轮数递减
for ((j=0; j<$length-$i; j++))
do
#获取第一个元素的值
first=${arr[$j]}   
#获取第二个元素的值
k=$[$j + 1]
second=${arr[$k]}
#比较第一个元素和第二个元素的值,如果第一个元素值大于第二个元素值则两个元素位置交换
if [ $first -gt $second ];then
#先把第一个元素的值保存在临时变量temp中
temp=${arr[$j]}
#把第二个元素的值赋给第一个元素
arr[$j]=$second
#把原来第一个元素的值赋给第二个元素
arr[$k]=$temp
done
done
echo "排序后新的数组的顺序为:${arr[@]}"

附加

sh [参数] 文件名.sh

  • -n 不要执行script,仅查询语法
  • -v 在执行script之前,先将script的内容输出到屏幕上
  • -x 将使用的脚本的内容输出到屏幕,该参数经常被使用
  • -c “string” 从strings中读取命令
  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值