定义
#!/bin/bash
#
# method one
name1()
{
echo "123"
}
# method two
function name2
{
echo "123"
}
function name3()
{
echo 123
}
- 三种方法都可以
- 这里后面所有用到的定义都是用
function name { command.. }
这样的方法
调用
# call function by name
name1
# 123
name2
# 123
name3
# 123
练习
- 使用一个函数来判断nginx是否在运行,如果不在运行则运行nginx
#!/bin/bash
#
# if nginx is down, start it
function nginx_start
{
# get pid
pid=$$
while true
do
ps -ef | grep nginx | grep -v grep | grep -v pid &> /dev/null
status=$?
if [ "$status" -eq 0 ] ; then
echo "Nginx is running well."
else
systemctl start nginx
echo "Nginx is down, start it...."
fi
sleep 3
done
}
# 如果这里不调用执行sh 命令是没有任何结果的。需要执行了sh后再执行nginx_start
nginx_start
补充关于$的特殊用法:
- $# 传递到脚本的参数个数
- $* 以一个单字符串显示所有向脚本传递的参数
- $$ 脚本运行的当前进程ID号
- $! 后台运行的最后一个进程的ID号
-
*相同,但是使用时加引号,并在引号中返回每个参数。
- $- 显示Shell使用的当前选项,与set命令功能相同。
- $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误
函数的参数
- 函数参数不需要像其他的编程语言一样有形参
- 函数参数可以直接在函数内使用 2 n
- 在使用
$(( ))
做运算的时候,一定要加$
符号
用法
#!/bin/bash
#
function params
{
echo "hello $1"
echo "hello $2"
echo "hello $3"
}
params params1 params2 123
# hello params1
# hello params2
# hello 123
案列
简单的计算器实现
#!/bin/bash
#
# a simple calculator
function calculator
{
case $2 in
+)
echo "`expr $1 + $3`"
;;
-)
echo "`expr $1 - $3`"
;;
\*)
echo "`expr $1 \* $3`"
;;
/)
echo "`expr $1 / $3`"
;;
esac
}
关于case的用法
case 值 in
匹配值1)
command1
command2
...
commandN
;;
匹配值2)
command1
command2
...
commandN
;;
esac
再次提醒: 需要先sh 这个文件 然后再在命令行中使用下列命令。
调用
calculator 12 + 3
# 15
calculator 12 - 3
# 9
calculator 12 * 3
# 36
calculator 12 / 3
# 4
函数返回值
- 函数的返回值可以有return 和 echo 两种方法
- return 一般做状态码返回 范围是1-255 后面不跟数字默认为0
- echo 作为结果值返回,一般可以为字符串、字符串列表 、数字等等 返回的结果直接打印在终端
案例
返回0 1 分别表示Nginx 在运行 和 不在运行
#!/bin/bash
#
# judge nginx was running
function is_nginx_running
{
pid=$$
ps -ef | grep nginx | grep -v grep &> /dev/null
status=`echo $?`
if [ $status -eq 0 ] ; then
# 默认返回0
return
else
return 1
fi
}
调用
is_nginx_running && echo "Ningx is running" || ehco "Ningx is Stop"
# Ningx is running
获取系统所有的用户
#!/bin/bash
#
# get all username
function get_users
{
users=`cat /etc/passwd | cut -d : -f1`
echo $users
}
# echo all users name
users=`get_users`
index=1
for s in $users
do
echo "The $index user is $s."
index=$(($index+1))
done
变量的作用域
- 在shell中如果不做特殊声明,那么变量不管是在函数体内还是函数外都是全局变量
- 如果要在函数内使用局部变量需要使用
local
关键字
- 谨慎使用全局变量。
- 函数没有运行 函数体定义的全局变量函数外部或者其他函数内部访问无效。
案列
#!/bin/bash
#
var1="hello world"
function test1
{
var2=123
}
function test2
{
local var3="local variable"
echo $var2
}
function test3
{
echo $var3
}
# 测试
echo $var1 $var2 $var3
# hello world
test1
test2
test3
echo $var1 $var2 $var3
# hello world 123
函数库
- 我们可以通过定义一些通用的函数或者复用度比较高的函数来形成我们的函数库
案例 : 定义加减乘除 和 显示系统信息的库
# add reduce multiple divide sys_load
function add
{
echo "`expr $1 + $2`"
}
function reduce
{
echo "$(($1 - $2))"
}
function multiple
{
echo "`expr $1 \* $2`"
}
function divide
{
echo "$(($1 / $2))"
}
function sys_load
{
echo "Memory Info : "
echo
free -m
echo
echo "Disk Usage"
echo
df -h
echo
}
使用函数库
- 我们需要先加载函数库 然后再使用
- 加载函数库 可以使用
.
或source
两种方法
- 函数库没有文件名后缀,不过在此建议大家使用lib 方便区分。当然也可不要文件后缀
#!/bin/bash
#
source ./lib/mylib.lib
# . ./lib/mylib.lib
add 1 2
reduce 2 1
multiple 2 2
divide 12 3
sys_load
3
1
4
4
Memory Info :
total used free shared buff/cache available
Mem: 1838 1003 89 0 746 645
Swap: 0 0 0
Disk Usage
文件系统 容量 已用 可用 已用% 挂载点
/dev/vda1 40G 16G 22G 42% /
devtmpfs 908M 0 908M 0% /dev
tmpfs 920M 4.0K 920M 1% /dev/shm
tmpfs 920M 580K 919M 1% /run
tmpfs 920M 0 920M 0% /sys/fs/cgroup
tmpfs 184M 0 184M 0% /run/user/0