bash脚本编程:
case语句:
case $VARAIBLE in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
分支n
;;
esac
case支持glob风格的通配符:
*:任意长度的任意字符;
?:任意单个字符;
[]:范围内任意单个字符;
a|b:a或b;
示例:写一个服务框架脚本;
$lockfile, 值/var/lock/subsys/SCRIPT_NAME
- 此脚本可接受start, stop, restart, status四个参数之一;
- 如果参数非此四者,则提示使用帮助后退出;
- start,则创建lockfile,并显示启动;stop,则删除lockfile,并显示停止;restart,则先删除此文件再创建此文件,而后显示重启完成;status,如果lockfile存在,则显示running,否则,则显示为stopped.
#!/bin/bash
#
#
#chkconfig: - 50 50
#description:test service
prog=$(basename $0)
file="/var/lock/subsys/$prog"
if [ $# -eq 0 ];then
echo "usage : $prog { start | stop | restart | status }"
exit 1
fi
case $1 in
'start')
touch $file
if [ $? -eq 0 ];then
echo 'service started'
fi
;;
'stop')
if [ -e $file ];then
rm -rf $file
echo 'service is stopped'
else
echo ' service had not been started '
fi
;;
'restart')
rm -rf $file && touch $file
if [ $? -eq 0 ];then
echo 'service restarted'
fi
;;
'status')
if [ -e $file ];then
echo 'service is running'
else
echo 'service is not started'
fi
;;
*)
echo "usage : $prog { start | stop | restart | status }"
;;
esac
函数:function
- 语法一:
function f_name { ... }
- 语法二:
f_name() { ... }
函数的生命周期:每次被调用时创建,返回时终止;
其状态返回结果为函数体中运行的最后一条命令的状态结果;
自定义状态返回值,需要使用:return
return [0-255]
0: 成功
1-255: 失败
示例:给定一个用户名,取得用户的id号和默认shell;
[root@localhost ~]# bash -x /scripts/e16_2-2.sh root
+ username=root
+ userinfo
+ id root
uid=0(root) gid=0(root) groups=0(root)
+ grep '^root\>' /etc/passwd
+ cut -d: -f3,7
0:/bin/bash
[root@localhost ~]# cat /scripts/e16_2-2.sh
#!/bin/bash
userinfo() {
id $username && grep "^$username\>" /etc/passwd |cut -d: -f3,7
}
username=$1
userinfo
示例2:服务脚本框架
函数返回值:
-
函数的执行结果返回值:
(1) 使用echo或printf命令进行输出;
(2) 函数体中调用的命令的执行结果; -
函数的退出状态码:
(1) 默认取决于函数体中执行的最后一条命令的退出状态码;
(2) 自定义:return -
函数可以接受参数:
- 传递参数给函数:
在函数体中当中,可以使用2, ...引用传递给函数的参数;还可以函数中使用@引用所有参数,$#引用传递的参数的个数;
在调用函数时,在函数名后面以空白符分隔给定参数列表即可,例如,testfunc arg1 arg2 arg3 ...
- 传递参数给函数:
练习:写一个脚本;
使用函数实现ping一个主机来测试主机的在线状态;主机地址通过参数传递给函数;
主程序:测试172.16.1.1-172.16.67.1范围内各主机的在线状态;
练习:写一个脚本;
打印NN乘法表;
变量作用域:
- 局部变量:作用域是函数的生命周期;在函数结束时被自动销毁;
定义局部变量的方法:local VARIABLE=VALUE
- 本地变量:作用域是运行脚本的shell进程的生命周期;因此,其作用范围为当前shell脚本程序文件;
示例程序:
[root@localhost ~]# bash /scripts/e16_2-3.sh
local :bar
global :foo
[root@localhost ~]# cat /scripts/e16_2-3.sh
#!/bin/bash
name=foo
setName() {
local name=bar
echo "local :$name"
}
setName
echo "global :$name"
函数递归:
- factorial
[root@localhost ~]# cat /scripts/e16_2-4.sh
#!/bin/bash
fac=1
factorial() {
if [ $1 -eq 1 ];then
let fac*=1
else
let fac*=$1
factorial $[$1-1]
fi
}
factorial $1
echo $fac
[root@localhost ~]# bash -x /scripts/e16_2-5.sh 5
+ factorial 5
+ '[' 5 -eq 1 ']'
++ factorial 4
++ '[' 4 -eq 1 ']'
+++ factorial 3
+++ '[' 3 -eq 1 ']'
++++ factorial 2
++++ '[' 2 -eq 1 ']'
+++++ factorial 1
+++++ '[' 1 -eq 1 ']'
+++++ echo 1
++++ echo 2
+++ echo 6
++ echo 24
+ echo 120
120
[root@localhost ~]# cat /scripts/e16_2-5.sh
#!/bin/bash
factorial() {
if [ $1 -eq 1 ];then
echo 1
else
echo "$[ $1 * $(factorial $[$1-1]) ]"
fi
}
factorial $1
- fibonacci
[root@localhost ~]# bash /scripts/e16_2-6.sh 6
1 1 2 3 5 8
[root@localhost ~]# cat /scripts/e16_2-6.sh
#!/bin/bash
fibonacci() {
if [ $1 -eq 1 ];then
echo -n "1 "
elif [ $1 -eq 2 ];then
echo -n "1 "
else
echo -n "$[$(fibonacci $[$1-1]) + $(fibonacci $[$1-2])] "
fi
}
for i in $(seq 1 $1);do
fibonacci $i
done
echo
[root@localhost ~]# cat /scripts/e16_2-7.sh
#!/bin/bash
f1=1;f2=1;temp=0
echo -n "1 1 "
for (( i=1;i<=$[$1-2];i++ ));do
temp=$f1
f1=$f2
f2=$[$f1+$temp]
echo -n "$f2 "
done
网友评论