shell编程——函数递归函数数组
Posted 可乐卷儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell编程——函数递归函数数组相关的知识,希望对你有一定的参考价值。
文章目录
一、shell函数定义
1、格式
将命令序列按格式写在一起,可方便重复使用命令序列
需要先定义函数名再调用,调用即在代码末写上函数名
格式一:
[ function ] 函数名(){
命令序列
[ return X]
}
格式二:
一般应用时,省略“[ function ] ”
函数名(){
命令序列
[ return X]
}
格式三:
function 函数名 {
}
2、实例
定义函数名叫hello,执行命令序列打印hello,要求输出hello
想要执行代码,需要把函数名写在最后面
- 格式一
#!/bin/bash
function hello(){ ##定义函数名 hello
echo hello ##命令序列
}
hello ##调用函数
- 格式二
#!/bin/bash
hello(){
echo hello
}
hello
3、调用函数
3.1、调用函数-脚本内
- 函数是常量时,若要调用函数的结果,需要加反撇号
#!/bin/bash
hello(){
echo hello
}
world(){
echo world
}
nihao(){
echo `hello` `world` ## 调用函数的结果,需要加反撇号
}
nihao
验证
- 函数是变量时
计算两个数的和;三种方式
#!/bin/bash
SUM(){
a=2
b=3
let sum=$a+$b
echo $sum
}
SUM
#! /bin/bash
sum(){
11
read -p “请输入一个数值: ” a
read -p “请输入一个数值: ” b
let sum=$a+$b
echo $sum
sum
SUM(){
let sum=$1+$2 ##脚本的位置变量$1和$2
echo $sum
}
SUM $1 $2 ##把脚本的$1$2调用给SUM
验证结果
3.2、调用函数-脚本外
- 先赋值后调用
当前shell环境内变量a=20
aaa(){
a=10
echo $a
}
a=20 ## 给a赋值220
aaa ## 此时的aaa是a=10的变量,输出10
echo $a ## 这时a的变量值为10.再次输出10
- 先调用后赋值
- 若一定要定义脚本内变量和脚本外的变量同名的话,需要脚本内的变量加上“local”,否则会跟脚本外的冲突;local作用范围仅在函数内部,不会对外部有影响
当前shell环境内变量a=20
这时脚本内的变量a=10,脚本内变量前面加上“local”之后发现输出的结果是 10;20
- 使用同名函数,后面的内容会被前面覆盖掉,所以函数名尽量不要一样
- 在一个脚本调用另外一个脚本的内容,需要使用source 绝对路径,刷新环境
先编辑脚本 hello.sh 函数名是www,输出world
这时在当前脚本需要刷新环境,再调用即可
3.2、调用函数-返回状态码
当一条命令执行成功,返回状态码为0,那若有多条命令时,如何取值呢?
- 返回码的结果取值函数的最后一条命令的返回结果
实例看下结果
调用hello成功了,但是lsxxx不成功,所以 echo $? 返回码是2,非0值
这时把ls xxxxx 放在命令序列内,查看返回码仍是非0值
- 使用return自定义一个返回码的值,值的范围0~255
不论脚本内的函数是否成功,均返回自定义返回码;此方法可以定位到具体的脚本,若脚本出错,直接找到对应定义的范围码位置即可
自定义返回码为20
- 脚本内看到ruturn就结束,这里返回码是10
4、实例
- 判断文件是否存在,存在返回该文件已存在,不存在返回该文件不存在
- 第一种
- 第二种
使用位置变量
- 第一种
- 计算用户指定的1-?的和
计算用户指定的1-?的偶数和
根据用户需求选择算总和还是偶数
#!/bin/bash
SUM(){
read -p "请输入你想计算1-几的和: " num
sum=0
for i in `seq $num` ##seq是一个序列的缩写,主要用来输出序列化的东西
do
let sum=$i+$num
done
echo $sum
}
oushu(){
read -p "输入你想计算1到几的偶数和:" n
sum=0
for i in `seq $n`
do
if [ $((i%2)) -eq 0 ];then
let sum=$i+$sum
fi
done
echo $sum
}
if [ $1 == 总和 ];then
SUM
elif [ $1 == 偶数 ];then
oushu
else
echo "参数错误"
fi
- 计算阶乘
- 第一种方法
#!/bin/bash
jiecheng(){
read -p "请输入几的阶乘:" num
cheng=1
for i in `seq $num`
do
let cheng=$i*$cheng
done
echo $cheng
}
jiecheng
- 第二种方法(位置变量)
#!/bin/bash
jiecheng(){
read -p "请输入几的阶乘:" num
cheng=1
for i in `seq $1`
do
let cheng=$i*$cheng
done
echo $cheng
}
jiecheng $1
二、递归函数
调用自己本身的函数
1、遍历文件夹
list_files( : : Directory, Options : Files)
Directory:目录(文件夹路径)
Options:选项
files ##指定搜索的格式为文件
directories ##指定搜索的格式为文件夹
recursive ##指定可以遍历子文件夹下的文件
follow_links
max_depth 5 ##指定遍历的深度
max_files 1000 ##指定遍历的最大文件数目
Files:文件(文件的路径)
2、文件格式筛选
tuple_regexp_select( : : Data, Expression : Selection)
Data:被选择的文件路径数组
Expression:文件格式的筛选规则
\\ ##转义
(bmp|JPG) ##筛选的文件格式
ignore_case ##忽略大小写
Selection ##选择出的文件路径数组
3、实例
- 利用shell脚本遍历指定路径下etc的所有文件
[root@localhost opt]# vim xc4.sh
#!/bin/bash
function list_files { ##定义递归遍历目录的函数
for f in `ls $1` ##循环遍历目录
do
if [ -d "$1/$f" ]
then ##判断若为目录则按格式输出目录名称并继续调用函数遍历这个目录
echo "$2$f"
list_files "$1/$f" "$2"
else ##判断若为文件则直接按照格式输出文件名称
echo "$2$f"
fi
done
}
list_files "/var/log" "" ##调用函数,第一个参数为要进行遍历的目录,第二个参数为格式设定,区分目录层级
验证
- 用函数递归的方式实现遍历目录,并显示层级效果,目录显示蓝色
#!/bin/bash
list_files() {
for f in `ls $1`
do
if [ -d "$1/$f" ]; then
echo -e "\\e[34m"$2$f"\\e[0m"
list_files "$1/$f""$2"
else
echo " $2$f"
fi
done
}
list_files "/var/log" ""
验证
三、数组
1、应用场景
- 获取数组长度
- 获取元素长度
- 遍历元素
- 元素切片
- 元素替换
- 元素删除
- …
2、数组定义的方法
- 方法一
数组名=(value0 value1 value2…) - 方法二
数组名=([0]=value [1]=value [3]=value…) - 方法三
列表名=“value0 value1 value2…”
数组名=($列表名) - 方法四
数组名[0]=“value”
数组名[1]=“value”
数组名[2]=“value”
3、数组包括的数据类型
- 数值类型
- 字符类型
- 使用“或”定义
4、实例
赋值一个数组
数组的下标第一个值是[0]
调用数组所有的下标
# ##显示有多少个
! ##显示数据的下标
echo ${a[*]} ##查看数组内容
echo ${#a[*]} ## 查看数组的个数
echo ${!a[@]} ##查看数组的下标
echo ${fruit[]} ##查看数组的个数
echo ${fruit[4]} ##查看下标4的数组内容
更改数组其中一个变量值
fruit[4]=boluo
echo ${fruit[]} ## 更改属主4为boluo
unset fruit[4] ## 删除数组[4]
查看索引,使用" ! "
查询系统有多少个用户
list=`cat /etc/passwd`
list1=($list)
echo ${#list1[*]}
元素切片
[root@klj ~]# a=(1 2 3 4 5)
[root@klj ~]# echo ${a[*]:2:3} ##从第二个数组切片3个,显示的是下标
3 4 5
[root@klj ~]# echo ${a[*]:1:3}
2 3 4
元素替换
[root@klj ~]# echo ${a[*]/5/15} ##搜索到数组5替换成15
1 2 3 4 15
利用数组打印1-5;三种方法
#!/bin/bash
a=(1 2 3 4 5)
for i in ${a[*]}
do
echo $i
done
#!/bin/bash
a=(1 2 3 4 5)
for ((i=0;i<${#a[*]};i++))
do
echo ${a[$i]}
done
#!/bin/bash
a=(1 2 3 4 5)
i=0
while [ $i -lt 5 ];
do
echo ${a[$i]}
let i++
done
验证
把1-10之间的偶数存到数组里面,并显示下标
现在有一个数组,a=(10 20 30 40 50),输出数组内最大的数
使用冒泡排序进行排序
#!/bin/bash
bubble(){
sum=(60 20 30 70 50)
for((i=0;i<${#sum[*]}-1;i++)) ##已比出最大值
do
for((j=0;j<${#sum[*]}-i-1;j++)) ## ${#sum[*]}-i-1 -i:自身已经比过了,
do
if [ ${sum[$j]} -gt ${sum[`expr $j + 1`]} ]
then
temp=${sum[$j]}
sum[$j]=${sum[`expr $j + 1`]}
sum[`expr $j + 1`]=$temp
fi
done
done
for((i=0;i<${#sum[*]};i++))
do
echo -n "${sum[$i]} "
done
echo ""
}
bubble
验证
把数组中不足60的加到60、删除数组中不足60分的元素
#!/bin/bash
num=(90 90 90 50 90 40 30 20)
for ((i=1;i<=${#num[*]};i++))
do
if [ $[num[$i-1]] -lt 60 ]
then
num[$i-1]=60
fi
done
echo ${num[*]}
#!/bin/bash
num=(90 50 60 45 30 90 90)
i=0
for j in ${num[*]}
do
if [ $j -lt 60 ]
then
unset num[$i]
fi
let i++
done
echo ${num[*]}
验证
以上是关于shell编程——函数递归函数数组的主要内容,如果未能解决你的问题,请参考以下文章