大家好,欢迎来到IT知识分享网。
1.shell函数概述
1.1 shell函数定义
函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程,它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分。
函数和shell程序区别
- shell程序在子shell中运行
- 函数在当前Shell中运行。因此在当前Shell中,函数可对shell中变量进行修改
shell函数:
使用函数可以避免代码重复
使用函数可以将大的工程分割为若干小的功能模块,代码的可读性更强
shell函数定义:
格式一:
function 函数名 {
命令序列 }
格式二:
函数名 (){
命令序列 }
查看函数
# 查看当前已定义的函数名 declare -F # 查看当前已定义的函数定义 declare -f # 查看指定当前已定义的函数名 declare -f func_name # 查看当前已定义的函数名定义 declare -F func_name
1.2 函数返回值
return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值
使用原则:
(1) 函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
(2) 退出状态码必须是0~255,超出时值将为除以256取余
函数的执行结果返回值:
使用echo等命令进行输出
函数体中调用命令的输出结果
函数的退出状态码:
默认取决于函数中执行的最后一条命令的退出状态码
自定义退出状态码,其格式为:
[root@clr /opt/mywork]# vim 20.sh #!/bin/bash function test01 {
read -p "请输入一个整数:" num return $[num *2] } test01 echo $? ~
1.3 函数变量的作用范围
- 函数默认只能在脚本内的shell环境有效(使用source执行脚本,也公影响系统当前的shell环境)
- 脚本中的变量默认全局有效(即函数体内外都有效)
[root@clr /opt/mywork]# vim 2.sh #!/bin/bash myfun() {
echo $name name=lisi echo $name name=zhangsan } main myfun echo $name
- 在函数体内执执行local 变量,可将变量限定在函数体内部使用,即local定义的变量值只能在函数体内部使用,出了函数体将无法使用;
[root@clr /opt/mywork]# vim 2.sh #!/bin/bash myfun() {
echo $name local name=lisi echo $name } main name=zhangsan myfun echo $name
2. 函数的调用
函数的调用方式
- 可在交互式环境下定义函数
- 可将函数放在脚本文件中作为它的一部分
- 可放在只包含函数的单独文件中
调用:==函数只有被调用才会执行,通过给定函数名调用函数(==直接执行函数名即可,不需要带小括号),函数名出现的地方,会被自动替换为函数代码
函数的生命周期:被调用时创建,返回时终止
[root@clr /opt/mywork]# vim 1.sh #!/bin/bash #定义函数 sum2() {
#函数体内部的$1 $2 代表的是调用函数时,函数后面跟的位置参数 sum=$[$1 - $2 ] echo $sum sum2() {
#函数体内部的$1 $2 代表的是调用函数时,函数后面跟的位置参数 sum=$[$1 - $2 ] echo $sum echo "在函数体内部的\$#代表调用函数时,函数后面跟的参数个数,当前>函数后面有$#个参数" echo "在函数体内部的\$@代表调用函数时,函数后面跟的所有参数,当前>函数后面的参数有:$@" echo "在函数体内部,\$0代表当前脚本$0" } echo "在函数体外时,\$#代表脚本后面跟的参数个数,当前脚本后面有$#个>参数" echo "在函数体外时,\$@代表脚本后面跟的所有参数,当前脚本后面参数有>:$@" echo "在函数体外,\$0代表当前脚本$0" #调用函数 #函数体外的$1 $2 代表的是执行脚本时,脚本后面跟的位置参数 sum2 $2 $1
3. 函数的递归
递归
函数调用自己本身的函数
递归调用,实现阶乘的计算;
[root@clr /opt/mywork]# vim 3.sh #!/bin/bash #使用函数的递归实现阶乘 fact() {
if [ $1 -eq 1 ];then echo 1 elif [ $1 -gt 1 ];then local tmp=$[$1 - 1] local res=$(fact $tmp) #在函数内调用函数 echo $[$1 * res] else echo "输入的值无效。请输入大于等于1的整数!" fi } main read -p "请输入一个大于等于1的整数:" num res=$(fact $num) echo "$num的阶乘值为$res"
例题演练一:
(1)使用函数递归目录/var/log,如果是文件直接输出文件名,如果是目录>则输出目录名且输出此目录下的所有目录和文件名;
[root@clr /opt/mywork]# vim 4.sh #!/bin/bash #使用函数递归目录/var/log,如果是文件直接输出文件名,如果是目录>则输出目录名且输出此目录下的所有目录和文件名 listf () {
for f in $(ls $1) do if [ -d "$1/$f" ];then echo "$2目录$f" listf "$1/$f" " $2" else echo "$2文件$f" fi done } #listf $(/var/log) $() listf "/var/log" $()
例题演练二:
(2)通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件;
[root@clr /opt/mywork]# vim 5.sh #!/bin/bash #通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件 #定义一个遍历PATH环境变量的函数 list_path() {
IFSB=$IFS IFS=$IFS':' for F in $PATH do echo "$F" done IFS=$IFSB } #定义一个递归函数 listf() {
for F in $(ls $1) do if [ -d "$1/$F" ];then echo "$2$F" listf "$1/$F" " $2" else if [ ! -x "$1/$F" ];then echo "$2$F" fi fi done } main #获取PATH变量的所有目录列表 folder=$(list_path) #遍历PATH变量的目录,并用函数递归查询 for path in $folder do echo $path listf "$path" " " done
例题演练三:
(3)将一个点分十进制格式的IP地址转换成点分二进制格式,比如 255.255.255.255 –> …;
[root@clr /opt/mywork]# vim 7.sh #将一个点分十进制格式的IP地址转换成点分二进制格式 #比如 255.255.255.255 --> ... #定义一个用于十进制转换为二进制的函数 switch_bin() {
NUM=$1 for i in {
1..8} do SUM=$[NUM % 2]$SUM let NUM/=2 done echo $SUM } #定义一个用于分割IP的函数 SPT() {
IP=$1 for i in {
1..4} do num=${
IP%%.*} IP=${
IP#*.} BIN=$(switch_bin num) echo -n $BIN. done } main read -p "请输入一个合法IP:" INIP res=$(SPT $INIP) echo ${
res%.*}
4. 函数库文件
可以将经常使用的函数存入一个单独的函数文件,然后将函数文件载入shell,再进行调用函数.
实现函数文件的过程:
- 创建函数文件,只存放函数的定义
- 在shell脚本或交互式shell中调用函数文件,格式如下:
. ./filename source filename
在脚本中加载函数库文件;
函数库文件:
[root@clr /opt/mywork]# vim clr.sh #!/bin/bash #函数库文件 jiafa() {
echo $[$1 + $2] } jianfa() {
echo $[$1 - $2] } chengfa() {
echo $[$1 * $2] } chufa() {
if [ $2 -eq 0 ];then echo "除数不可为0" else echo $[$1 / $2] fi } fact() {
if [ $1 -eq 1 ];then echo 1 elif [ $1 -gt 1 ];then local tmp=$[$1 - 1] local res=$(fact $tmp) #在函数内调用函数 echo $[$1 * res] else echo "输入的值无效。请输入大于等于1的整数!" fi }
在脚本中加载函数库文件:
[root@clr /opt/mywork]# vim 8.sh #!/bin/bash #加载函数库文件到当前脚本的shell source /opt/mywork/clr.sh value1=10 value2=5 res1=$(jiafa $value1 $value2) res2=$(jianfa $value1 $value2) res3=$(chengfa $value1 $value2) res4=$(chufa $value1 $value2) res5=$(fact $value1 $value2) echo "加法的结果为$res1" echo "减法的结果为$res2" echo "乘法的结果为$res3" echo "除法的结果为$res4" echo "阶乘的结果为$res5"
5.总结
函数
定义函数
(1)function 函数名 {代码块}
(2)函数名 () {代码块}
返回函数的值
(1)在函数内用return退出函数并返回函数的值,在函数外用echo $?获取返回值
注意:返回值的范围只能在0~255,超过部分需除以256取余
(2)在函数内用echo输出值,在函数体外可用 变量=$(函数名) 获取函数的返回值
如何给函数传参
函数变量的作用范围
函数默认只能在脚本内的shell环境有效(使用source执行脚本,也公影响系统当前的shell环境)
脚本中的变量默认全局有效(即函数体内外都有效)
在函数体内执执行local 变量,可将变量限定在函数体内部使用
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/118314.html












