函数的数学表达式
sin cos tan 其实就是定义好了计算公式 函数就是一个功能模块,在函数中写好执行的命令即可
使用函数可以避免代码重复,增加可读性, 简化脚本
使用函数可以将大的工程分割为若干小的功能模块,代码的可读性更强
函数使用方法:
定义函数
再引用函数
基本格式:
1、
function 函数名{
命令序列
}
2、
函数名 (){
命令序列
}
3、
function 函数名(){
命令序列
}
注意事项
直接写函数名 调用函数
同名函数 后一个生效
调用函数一定要先定义
每个函数是独立
func_name (){
...函数体...
}
[root@localhost ~]#func1 (){ hostname;date;}
#定义函数
[root@localhost ~]#func1
#调用函数
localhost.localdomain
2024年 01月 26日 星期五 23:46:00 CST
#!/bin/bash
h () {
echo "hello"
}
h
declare -F
declare -F
#查看当前已定义的函数名
[root@localhost ~]# declare -F
#函数列表
declare -f __HOSTNAME
declare -f __SIZE
declare -f __SLAVEURL
-------------过多省略------------------
declare -f
#查看当前已定义的函数定义
declare -f func_name
#查看指定当前已定义的函数名
[root@localhost ~]#declare -f test1
test1 ()
{
read -p "请输入一个数字:" num;
return $[$num*2]
}
declare -F func_name
#查看当前已定义的函数名定义
[root@localhost ~]#declare -F test1
test1
unset 函数名
[root@localhost ~]#func1 (){ hostname;date;}
[root@localhost ~]#func1
localhost.localdomain
2024年 01月 26日 星期五 23:46:00 CST
[root@localhost ~]#unset func1
[root@localhost ~]#func1
bash: func1: 未找到命令...
return 表示退出函数并返回一个退出值,脚本中可以用 $? 变量表示该值
通常 $? 表示上一次命令的执行结束是否正确,0 为正确,其它表示错误。echo $?
使用原则:
1. 函数一结束就去返回值,应为$?变量只返回执行的最后一条命令的退出返回码
2. 退出码必须是0-255,超出的值将为除以256取余
【return】
函数的退出状态码:
默认取决于函数中执行的最后一条命令的退出状态码
自定义退出状态码,其格式为:
return 从函数中返回,用最后状态命令决定返回值
return 0 无错误返回
return 1-255 有错误返回
#!/bin/bash
test1 () {
read -p "请输入一个数字:" num
return $[$num*2]
}
test1
echo $?
#可以看到返回的结果为 两倍的 num
怎么解决超过 255
#!/bin/bash
test1 () {
read -p "请输入一个数字:" num
echo $[$num*2]
}
result=`test1`
echo $result
return 的用法:
user () {
if [ $USER = root ]
then
echo "这是管理员用户"
else
echo "这不是管理员用户"
return 1
fi
}
user
[root@localhost ~]#vim chuan.sh
#!/bin/bash
sum1 (){
echo $1 #输出第一个位置参数
echo $2 #输出第二个位置参数
}
sum1 $2 $1 #调用函数 并把 输出的第二个位置参数 放在第一个 ,然后把 输出的第一个位置参数 放在第二个
不加位置变量($1)无法输出。
#如下所示 :abc 是 第一个位置参数 ,bcd 是第二个位置参数
[root@localhost ~]#bash chuan.sh abc bcd
bcd
abc
脚本 使用函数 判断操作系统类型 ,并安装相应的 httpd 安装包
#!/bin/bash
os (){
if grep -i -q ubuntu /etc/os-release
then
echo "ubuntu"
elif grep -i -q centos /etc/os-release
then
echo "centos"
else
echo "os not support!"
fi
}
if [ `os` = centos ]
then
yum install httpd -y
elif [ `os` = ubuntu ]
then
apt install apache2 -y
else
echo "os not support!"
fi
函数在shell脚本中仅在当前的shell环境中有效
shell 脚本中函数的变量默认全局有效
将变量限定在函数内部使用 local 命令
[root@localhost opt]# vim demo8.sh
#!/bin/bash
myfun(){
i=8
echo $i #输出变量
}
myfun #调用函数
[root@localhost opt]#bash demo8.sh
8
[root@localhost opt]# vim demo8.sh
#!/bin/bash
myfun(){
i=8
echo $i
}
myfun
echo $i #输出当前环境的变量i
[root@localhost opt]#bash demo8.sh #注意 bash 是在子环境里运行脚本
8
8 #可以看到 函数里的变量在当前环境中有效
[root@localhost opt]# vim demo8.sh
#!/bin/bash
myfun(){
i=8
echo $i
}
i=9 #在调用函数前先定义变量为 9 。
myfun #调用函数
echo $i #输出当前环境的变量i
[root@localhost opt]# ./demo8.sh
8
8
#可以看到 事先定义的变量在调用过函数后发生了改变,已经不再是9了。
#注意 ,在调用函数之前 ,函数里面定义的变量以及命令都不会生效。
[root@localhost opt]# vim demo8.sh
#!/bin/bash
myfun(){
i=8
echo $i
}
myfun
i=9 #在调用函数后再定义 一次变量。
echo $i
[root@localhost opt]# ./demo8.sh
8
9
#可以看到 调用函数后更改变量才会有效。
local 命令
[root@localhost opt]# cat demo8.sh
#!/bin/bash
myfun(){
local i=8 #将变量限定在函数内部使用
echo $i
}
i=9
myfun
echo $i
[root@localhost opt]#bash demo8.sh
8
9
#因变量被限制在函数内部,所以不会影响事先定义的变量
[root@localhost ~]#name=qian
[root@localhost ~]#func1 () { name=li ; echo $name; }
[root@localhost ~]#func1
li
[root@localhost ~]#echo $name
li
[root@localhost ~]#name=qian;func1 () { local name=li ;echo $name; };echo $name
#加上local变量即可将变量限制在函数内
qian
我们可以新建一个专门存放函数的文件
[root@localhost ~]#vim mlall #建立专门的函数文件
#!/bin/bash
lsos () {
if grep -i -q centos /etc/os-release
then
echo "系统是centos"
elif grep -i -q ubuntu /etc/os-release
then
echo "系统是ubuntu"
else
echo this os is not centos and ubuntu
fi
}
color () {
red="echo -e \E[31m"
green="echo -e \E[32m"
end="\E[0m"
}
#这个不如直接定义变量。
red="echo -e \E[31m"
green="echo -e \E[32m"
end="\E[0m"
#使用方法 ${red}写上你要输出的内容就会改变颜色了${end}
[root@localhost ~]#. mlall #使用次命令在当前shell环境运行此函数文件。
[root@localhost ~]#lsos
系统是centos
1.函数调用自己本身的函数
2.必须要有结束函数的语句,防止死循环
阶乘
阶乘是基斯顿·卡曼于 1808 年发明的运算符号,是数学术语
一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0和1的阶乘为1,自然数n的
阶乘写作n!
n!=1×2×3×...×n
阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n
n!=n(n-1)(n-2)...1
n(n-1)! = n(n-1)(n-2)!
实例:
#谨慎使用此脚本,这可能导致机器死机。
#!/bin/bash
#
fact() {
if [ $1 -eq 0 -o $1 -eq 1 ]
then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
fact $1
运行时后面一定要加位置参数
用for循环
#!/bin/bash
sum=1
read -p "请输入一个数字:" num
for i in `seq $num`
do
let sum=$[i*sum]
done
echo $sum
递归目录:
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" ""
将全班学生定义成一个变量,无法使用普通变量。
普通数组
关联数组
变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组名和索引
索引的编号从0开始,属于数值索引
索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash 4.0版本之后开始支持
bash的数组支持稀疏格式(索引不连续)
定义数组格式:
数组名=(value0 value1 value2 value3 ......)
数组名=([0]=value [1]=value1 [2]=value2 ....)
列表名="value0 value1 value2 value3 ...... "
数组名=($列表名)
数组名[0]="value1"
数组名[1]="value2"
数组名[2]="value3"
数组的包括数据类型
数值型
字符型
混合型数值加字符
使用" "或' '定义 用单引号或双引号括起来
关于数组:
[root@localhost ~]# a=(a b c d e f)
#定义数组
如何查看定义的数组?
1、
[root@localhost ~]#declare -a
declare -a a='([0]="a" [1]="b" [2]="c" [3]="d" [4]="e" [5]="f")'
2、
[root@localhost ~]#echo ${a[*]} //*代表所有参数
a b c d e f
[root@localhost ~]#echo ${a[@]} //@同*
a b c d e f
如何查看下标?
[root@localhost ~]#echo `echo ${!a[*]}`
0 1 2 3 4 5
#表示(a b c d e f)所在位置
如何查看数组的长度?
1、
[root@localhost ~]# echo ${#a[@]} //前面加#数组的长度
6
[root@localhost ~]# echo ${#a[*]}
6
数组分隔(切片):
${数组名[@]:offset:number}
offset #要跳过的元素个数
number #要取出的元素个数
#取偏移量之后的所有元素
[root@localhost ~]#echo ${a[*]}
a b c d e f
#数值a b c d e f
#位置0 1 2 3 4 5
[root@localhost ~]#echo ${a[*]:2:3} #从2开始往后显示三个数(数组内数值位置是从0开始算的)
c d e
[root@localhost ~]#echo ${a[*]:0:5} #从0开始显示五个数
a b c d e
[root@localhost ~]#num=({1..10})
[root@localhost ~]#echo ${num[*]}
1 2 3 4 5 6 7 8 9 10
#数值1 2 3 4 5 6 7 8 9 10
#位置0 1 2 3 4 5 6 7 8 9
[root@localhost ~]#echo ${num[*]:6} #从位置6开始显示
7 8 9 10
数组替换:
[root@localhost ~]#echo ${a[*]}
a b c d e f
[root@localhost ~]#a[1]=9 #位置1的数替换为9
[root@localhost ~]#echo ${a[*]}
a 9 c d e f
改变数组显示:
[root@localhost ~]#echo ${a[*]/f/qwq} #把f变为qwq显示出来。
a 9 c d e qwq
#只是改变了显示,并没有真正的修改
[root@localhost ~]#echo ${a[*]}
a 9 c d e f
列表与数组:
[root@localhost ~]#wu="1 2 3 4 5"
#先定义列表
[root@localhost ~]#wu1=($wu)
#再定义数组
[root@localhost ~]#echo ${wu1[@]}
1 2 3 4 5
1、取出数组内的最大值与最小值
#!/bin/bash
read -p "请输入正整数字,并已空格隔开:" num
a=( $num )
max=${a[0]}
for ((i=0;i<${#a[*]};i++))
do
if [[ $max -lt ${a[$i+1]} ]]
then
max=${a[$i+1]}
fi
done
echo "最大值是$max"
min=${a[0]}
for ((i=0;i<${#a[*]}-1;i++))
do
if [[ $min -ge ${a[$i+1]} ]]
then
min=${a[$i+1]}
fi
done
echo "最小值是$min"
合并在一起并随机生成数字
#!/bin/bash
declare -i min max #声明整数型变量
declare -a a #声明数组变量
for ((i=0;i<10;i++))
do
a[$i]=$[RANDOM%1000]
[ $i -eq 0 ] && max=${a[0]} && min=${a[0]} &&continue
[[ ${a[$i]} -gt $max ]] && max=${a[$i]} && continue
[[ ${a[$i]} -lt $min ]] && min=${a[$i]}
done
echo ${a[*]}
echo max=$max
echo min=$min
2、对数组内的数字排序(排序算法,冒泡算法)
#!/bin/bash
a=(90 20 30 40 50)
# 0 1 2 3 4 下标
l=${#a[@]}
for ((i=1;i<$l;i++))
do
for ((j=0;j<${l}-1;j++))
do
first=${a[$j]}
k=$[$j+1]
second=${a[$k]}
if [ $first -gt $second ]
then
temp=$first
a[$j]=$second
a[$k]=$temp
fi
done
done
echo ${a[@]}