case语句shell
何时用到case?bash
当屡次判断变量是否属于某个字符串时候框架
case语句的语法格式:ide
case $VARAIBLE in 函数
PAT1) 注:若是PAT1匹配到$VARAIBLE时候,执行分支1 同理测试
分支1ui
;; 注:每个判断条件都要双分号,同理spa
PAT2) rest
分支2orm
;;
...
*) 都不属于以上状况,执行分支n
分支n
;;
esac 最后一个不须要
特性:case支持glob风格的通配符:
*:任意长度的任意字符;
?:任意单个字符;
[]:范围内任意单个字符;
a|b:a或b;
case简单示例:写一个服务框架脚本;
(1) 此脚本可接受start, stop, restart, status四个参数之一;
(2) 若是参数非此四者,则提示使用帮助后退出;
(3) start,则建立lockfile,并显示启动;stop,则删除lockfile,并显示中止;restart,则先删 除此文件再建立此文件,然后显示重启完成;status,若是lockfile存在,则显示running,不然,则显示为stopped.
#!/bin/bash # # chkconfig: - 50 50 注:定义运行级别、启动优先级、关闭优先级 # description: test service script 注:描述信息 # prog=$(basename $0) 注:以变量替换的方式取路径基名,并赋值给变量prog lockfile=/var/lock/subsys/$prog 注:给变量lockfile赋值一个文件路径 case $1 in start) if [ -f $lockfile ]; then 注:-f进行文件存在性测试 echo "$prog is running yet." else touch $lockfile [ $? -eq 0 ] && echo "start $prog finshed." 注:以命令状态返回值判断 fi 文件是否建立成功 ;; stop) if [ -f $lockfile ]; then 逻辑同理 rm -f $lockfile [ $? -eq 0 ] && echo "stop $prog finished." else echo "$prog is not running." fi ;; restart) if [ -f $lockfile ]; then rm -f $lockfile touch $lockfile echo "restart $prog finished." else touch -f $lockfile echo "start $prog finished." fi ;; status) if [ -f $lockfile ]; then echo "$prog is running" else echo "$prog is stopped." fi ;; *) echo "Usage: $prog {start|stop|restart|status}" exit 1 esac
函数:function
为何要用到函数?
为了简化本身写的代码量,重复屡次使用的功能能够包装成函数屡次调用。也会使你的代码更有结构
什么是函数?
把一段独立功能的代码看成一个总体,并为之一个名字;命名的代码段,此即为函数;
怎样使用函数?
定义函数的代码段不会自动执行,在调用时执行;所谓调用函数,在代码中给定函数名便可;
函数名出现的任何位置,在代码执行时,都会被自动替换为函数代码;函数的生命周期:每次被调用时建立,返回时终止;
语法一:
function f_name {
...函数体...
}
语法二:
f_name() {
...函数体...
}
自定义状态返回值方法:
其状态返回结果为函数体中运行的最后一条命令的状态结果;
自定义状态返回值,须要使用:return
return [0-255]
0: 成功
1-255: 失败
函数的执行结果返回值:
(1) 使用echo或printf命令进行输出;
(2) 函数体中调用的命令的执行结果;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
函数使用举例1:给定一个用户名,取得用户的id号和默认shell;
#!/bin/bash # userinfo() { if id "$username" &> /dev/null; then grep "^$username\>" /etc/passwd | cut -d: -f3,7 else echo "No such user." fi } username=$1 userinfo username=$2 userinfo
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
函数使用举例2:服务脚本框架
#!/bin/bash # # chkconfig: - 50 50 # description: test service script prog=$(basename $0) lockfile=/var/lock/subsys/$prog start() { 注:函数定义 if [ -f $lockfile ]; then echo "$prog is running yet." else touch $lockfile [ $? -eq 0 ] && echo "start $prog finshed." fi } stop() { if [ -f $lockfile ]; then rm -f $lockfile [ $? -eq 0 ] && echo "stop $prog finished." else echo "$prog is not running." fi } status() { if [ -f $lockfile ]; then echo "$prog is running" else echo "$prog is stopped." fi } usage() { echo "Usage: $prog {start|stop|restart|status}" } case $1 in start) start ;; 注:调用start函数,如下同理 stop) stop ;; restart) stop start ;; status) status ;; *) usage exit 1 ;; esac
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
函数能够接受参数:
1.在函数体中当中,可使用$1,$2, ...引用传递给函数的参数;
2.还能够函数中使用$*或$@引用全部参数,
3. $#引用传递的参数的个数;
例如,testfunc arg1 arg2 arg3 ...
注:在调用函数时,在函数名后面以空白符分隔给定参数列表便可
示例:添加10个用户,
添加用户的功能使用函数实现,用户名作为参数传递给函数;
函数能够接受参数举例1
#!/bin/bash # # 5: user exists addusers() { if id $1 &> /dev/null; then return 5 else useradd $1 retval=$? return $retval fi } for i in {1..10}; do addusers ${1}${i} retval=$? if [ $retval -eq 0 ]; then echo "Add user ${1}${i} finished." elif [ $retval -eq 5 ]; then echo "user ${1}${i} exists." else echo "Unkown Error." fi done
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
练习:写一个脚本;
使用函数实现ping一个主机来测试主机的在线状态;主机地址经过参数传递给函数;
主程序:测试172.16.1.1-172.16.67.1范围内各主机的在线状态;
练习:写一个脚本;
打印NN乘法表;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
变量做用域
局部变量:做用域是函数的生命周期;在函数结束时被自动销毁;
定义局部变量的方法:local VARIABLE=VALUE
本地变量:做用域是运行脚本的shell进程的生命周期;所以,其做用范围为当前shell脚本程序文件;
变量做用域举例1
#!/bin/bash # name=tom setname() { local name=jerry echo "Function: $name" } setname echo "Shell: $name"
函数递归
函数直接或间接调用自身;
10!=10*9!=10*9*8!=10*9*8*7!=...
n*(n-1)!=n*(n-1)*(n-2)!=
函数递归举例1
#!/bin/bash # fact() { if [ $1 -eq 0 -o $1 -eq 1 ]; then echo 1 else echo $[$1*$(fact $[$1-1])] fi } fact $1
函数递归举例2
1,1,2,3,5,8,13,21,...
#!/bin/bash # fab() { if [ $1 -eq 1 ]; then echo -n "1 " elif [ $1 -eq 2 ]; then echo -n "1 " else echo -n "$[$(fab $[$1-1])+$(fab $[$1-2])] " fi } for i in $(seq 1 $1); do fab $i done echo
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
编外扩展
示例1:显示一个菜单给用户;
cpu) display cpu information
mem) display memory information
disk) display disks information
quit) quit
要求:(1) 提示用户给出本身的选择;
(2) 正确的选择则给出相应的信息;不然,则提示从新选择正确的选项;
#!/bin/bash # cat << EOF cpu) display cpu information mem) display memory infomation disk) display disks information quit) quit =============================== EOF read -p "Enter your option: " option while [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]; do echo "cpu, mem, disk, quit" read -p "Enter your option again: " option done if [ "$option" == "cpu" ]; then lscpu elif [ "$option" == "mem" ]; then free -m elif [ "$option" == "disk" ]; then fdisk -l /dev/[hs]d[a-z] else echo "quit" exit 0 fi