持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
王志远,微医前端技术部
Shell 的函数、模块化、公共函数库
shell 之函数
用于重复命令逻辑的集合
- 函数的定义和执行
- 函数参数
- 函数的作用范围
- 模块化
- 系统自建函数库
函数的定义和执行
定义
# function 关键词可以省略
function fname(){
命令
}
执行
fname
实例
# function 关键词可以省略
function cdls() {
cd /var
ls
}
cdls
函数变量
分为内部定义的变量和外部的传参
内部定义
local 变量名
外部传参
调用
funcName a b
这里有巨坑:
- 函数的返回值(return)只支持数字类型,所以我们需要使用 echo 输出流的形式巧妙的模拟返回其他类型数据
function funcName(){
echo aaa
}
returnContent=`funcName`
- 如果参数中包含了空格,一定要在传递时用引号包裹,不然会被解析成多个参数(比如数组)
arr=(a b c)
funcName "${arr[@]}"
- 参数和返回值只支持字符串,所以如果想支持数组,可以采用如下方式:
- 入参:将数组的所有内容转为字符串传递,再在内部转为数组
- 返回值:将数组的所有内容转为字符串返回,再在外部转为数组
<<'COMMENT'
追加元素
@param arr 数组名
@param item 被追加的元素
@return 改变后的数组字符串
COMMENT
function push() {
# 获取数组名
local name=$1
# 获取数组内容,创造一个对应的内部数组
eval local innerArr=(\${${name}[@]})
local item=$2
innerArr+=($item)
# 先清除的尝试 失败
# local length=${#innerArr[@]}
# eval unset $name
# for((i=0;i<$length;i++)); do
# eval unset $name[$i]
# done
echo ${innerArr[@]}
}
arr=(a b c)
arr=(`push arr aaa`) # 这里的数组已经成为(a b c d)
echo arr===${arr[@]}
内部使用
$1 $2 $3...$n
注意点
- 如果两位数了,假如是 10,就需要使用${10}
- $#:参数个数总数
- $*:作为字符串输出所有参数
-
- *相同,但是使用时加引号,并在引号中返回每个参数
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
实例之传参
# function 关键词可以省略
function cdls() {
cd $1
ls
}
cdls /tmp
实例之内部变量
# function 关键词可以省略
function checkpid() {
local i
for i in $*; do
# linux 中,每个在运行的进程都会有一个在/proc 目录下对应的子目录,目录名为 pid,这也是 ps
[ -d "/proc/$i" ] && return 0
done
}
checkpid 5380
echo $?
模块化
其实 shell 的模块化(即函数的导入导出)非常简单,我们知道 shell 会话间的变量是互通的(函数中的 local 变量除外),这时我们只要以当前 shell 会话执行下定义函数的 sh,就能访问到对应的函数了。而如何以当前 shell 执行呢?就是之前讲到的知识:以 source 或者.方式执行 sh 文件。
引入
引入方式很简单
source [函数库的绝对路径]
./11.sh
source 11.sh
bash 11.sh
~ 11.sh
sh
bash
案例
存在函数库 libs/os.sh
#!/bin/bash
# 获取当前系统类型
# @return platForm
function getPlatForm() {
local innerPlatForm
if [[ $(uname) == 'Darwin' ]]; then
innerPlatForm=mac
fi
if [[ $(uname) == 'Linux' ]]; then
innerPlatForm=linux
fi
if [[ $(uname) == 'win32' ]]; then
innerPlatForm=window
fi
# shell 的 function 只能返回整数值,所以如果想接收字符串类型 echo+$()方式获取
echo $innerPlatForm
}
引入使用时
source ./libs/os.sh
# 执行函数
platForm=$(getPlatForm)
# 看输出结果
echo $platForm
注意事项
- shell 的 function 中的 return 语句只能返回整数值,所以如果想接收字符串类型 echo+$()方式获取
系统自建函数库
linux 系统中存在自带的函数库,地址如下
/etc/init.d/functions
在配置文件中也是用了大量的循环判断,可以看/etc/profile或者/etc/.bashrc