shell函数
功能
- 使用函数可以避免代码重复
- 使用函数可以将大的工程分割为若干小的功能模块,代码的可读性更强
一:函数的定义方法
方法一
function 函数名 {
命令序列
}
举例:
function user {useradd $nameecho 123456 | passwd --stdin $name
方法二
函数名() { #注意函数名后面那个小括号里面什么都不要写,固定格式
命令序列
}
举例:
user() {useradd $nameecho 123456 | passwd --stdin $name
}
################main#############'
read -p "输入你要创建的用户名" name
user
二:获取shell函数的返回值
方法一(不常用)
return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值
使用原则:
- 函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
- 退出状态码必须是0~255,超出时值将为除以256取余数
示例:
方法二 (常用)
在函数内用echo输出值,在函数体外可用 变量=S(函数名) 获取函数的返回值
三:函数传参
1:位置参数在函数体内
- 函数体内部的$1 ,$2 代表的是调用函数时,函数后面跟的位置参数在函数体内部的
- $#代表调用函数时,函数后面跟的参数个数在函数体内部的
- $@ $*代表调用函数时,函数后面跟的所有参
2:位置参数在函数体外
- 函数体外的$1 $2 代表的是执行脚本时,脚本后面跟的位置参数
- 在函数体外时 $# 代表脚本后面跟的参数个数
- 在函数体外时 $@ $*代表脚本后面跟的所有参数
3:特殊情况 $0
- 不管在函数体内还是在函数体外,$0都代表脚本本身
示例:
四:函数变量的作用范围:
- 函数默认只能脚本内的shel1环境有效(使用source执行脚本,也会影响系统的当前shel环境)
- 脚本中的变量默认全局有效(即函数体内外都有效)
- 在函数体内执行 local 变量 ,可将变量限定在函数体内部使用,外部就不能用
myfun() {echo $namelocal name=lisiecho $name}###main#########name=zhangsan
myfun
echo $name#local限定的函数内,函数内的变量成为了局部变量(新的变量,只在函数体内有效;是局部变量,退出函数后就会失效)
拓展:
1、linux的全局变量与局部变量
- 全局变量:作用于整个操作系统内所有用于的shell环境内,
- 局部变量:变量只作用于当前shell环境内
2、shell脚本的全局变量与局部变量
- 全局变量:作用于shell脚本当前的整个shell环境中,包括函数体内或者体外。
- 局部变量:作用于shell脚本当前的shell环境中,仅限制于某个函数体内。
五:递归
函数调用自己本身的函数,直到满足不再递归的条件。
如何使用函数的递归实现阶乘
阶乘含义:5的阶乘即 “ 5!”=5 * 4 * 3 * 2 * 1 。
如何使用函数的递归实现阶乘:
#使用函数的递归实现阶乘
fact() {if [ $1 -eq 1 ]thenecho 1elselocal temp=$[ $1 - 1 ]local result=$(fact $temp)
#使用local规定全局变量,用来防止函数内变量与主代码区变量相冲echo $[$1 * $result ]fi
}
############## main #############
read -p "请输入:" n
result=$(fact $n)
echo $result
通过函数实现递归查看目录
#!/bin/bash
#使用函数递归目录/var/log,如果是文件直接输出文件名,如果>是目录则输出目录名且输出此目下录的所有目录和文件名
listf() {for d in $(ls $1)doif [ -d "$1/$f" ]thenecho "$2目录$f"listf "$1/$f" " $2"elseecho "$2文件$f"fidone
}
#######################main###########
listf "/var/log" ""
拓展实验:通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件
拓展:将一个点分十进制格式的IP地址转换成点分二进制格式
六:函数库
先定义一个函数库
将函数库文件加载到当前脚本的shell
执行脚本即可使用函数库里面的已经定义好的函数