回顾: 循环
循环控制:break,continuewhile , for循环的特殊用法for (());do 循环体donewhile read VARAIBLE;do 循环体done < /PATH/FROM/SOMEFILE
bash脚本编程:
case语句: 多分支语句: if CONDITION1;then 分支1 elif CONDITION2;then 分支2 ... else CONDITION;then 分支n fi
示例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 infomration disk) display disks information quit) quit ===================== EOFread -p "Enter your option:" optionwhile [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]do echo "cpu,mem,disk,quit" read -p "Enter your option again:" optiondoneif [ "$option" == "cpu" ];then lscpuelif [ "$option" == "mem" ];then free -melif [ "$option" == "disk" ];then df -helif [ "$option" == "quit" ];then exitfi
case语句的语法格式:只适用于一个变量反复跟多个字符串等值或者不等值比较时,来匹配。
case $VARAIBLE inPAT1) 分支1 ;; PAT2) 分支2 ;; *) 分支n ;; esac
示例1 使用上边的脚本,把通过if的代码,来用case语句实现
#!/bin/bash##cat << EOF cpu) display cpu information mem) display mem information disk) display disks information quit) exitEOFread -p "Enter your option :" optionwhile [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]do echo "cpu,mem,disk,quit" read -p "Enter your option again :" optiondonecase $option incpu) lscpu ;; mem) free -m ;; disk) df -h ;; quit) exit;;esac
示例2:写一个服务框架脚本;
$lockfile,值/home/soft/SCRIPT_NAME
(1)此脚本可接受start,stop,restart,status四个参数之一;
(2)如果参数非此四者,则提示使用帮后退出;
(3)start,则创建lockfile,并显示启动;stop,则删除lockfile,并显示停止;restart,则先删除文件在创建此文件,而后显示重启完成;status,如果lockfile存在,则显示running,否则,则显示为stopped。
#!/bin/bash#prog=$(basename $0) lockfile=/home/soft/$progcase $1 instart) if [ -f $lockfile ];then echo "$prog is running" else touch $lockfile [ $? -eq 0 ] && echo "start $prog finshed" fi ;; stop) if [ -f $lockfile ];then rm -f $lockfile [ $? -eq 0 ] && echo "stop $prog finshed" else echo "$prog is not running" fi ;; restart) if [ -f $lockfile ];then rm -f $lockfile touch $lockfile echo "$prog is restart" else touch -f $lockfile echo "start $prog finshed" fi ;; status) if [ -f $lockfile ];then echo "$prog is running" else echo "$prog is stopped" fi ;; *) echo "Usage: $prog {start|stop|restart|status}" exit 1esac
函数:function
过程是编程:代码重用 模块化编程 结构化编程 把一段独立功能的代码当做一个整体,并为之一个名字;命名的代码段,此即为函数; 注意:定义函数的代码段不会自动执行,再调用时执行;所谓调用函数,在代码中给定函数名即可;函数名出现的任何位置,在代码执行时,都会被自动替换为函数代码;
语法一
function f_name { …函数体… }
语法二
f_name() { …函数体… }
函数的生命周期:每次被调用时创建,返回时终止;
其状态返回结果为函数体重运行的最后一条命令的状态结果; 自定义状态返回值,需要使用:returnreturn[0-255]0是成功1-255失败
示例1:给定一个用户名,取得用户Id号和默认shell;
正常不用函数来写这段代码的话是这样的
#!/bin/bash#if id "$1" &> /dev/null ;then grep "^$1\>" /etc/passwd | cut -d: -f 3,7else echo "NO such user"fi
用函数来定义 注意:函数里边不能直接用$1..来直接充当参数。
#!/bin/bash#if id "$1" &> /dev/null ;then grep "^$1\>" /etc/passwd | cut -d: -f 3,7else echo "NO such user"fi[root@centous1 lianxi]# bash +x user2.sh user1^C
这个时候直接运行时是没有结果的,我们需要调用这个函数。
#!/bin/bash#userinfo() { if id "$username" &> /dev/null;then grep "^$username\>" /etc/passwd |cut -d: -f 3,7else echo "NO such user"fi} username=$1userinfo [root@centous1 lianxi]# bash +x user2.sh user14323:/bin/bash
同时,我们还可以多次调用
#!/bin/bash#userinfo() { if id "$username" &> /dev/null;then grep "^$username\>" /etc/passwd |cut -d: -f 3,7else echo "NO such user"fi} username=$1userinfo username=$2userinfo [root@centous1 lianxi]# bash +x user2.sh user1 user24323:/bin/bash4324:/bin/bash
示例2:把前边的服务脚本用函数来编写
#!/bin/bash#prog=$(basename $0) lockfile=/home/soft/$progstart (){ if [ -f $lockfile ];then echo "$prog is running" else touch $lockfile [ $? -eq 0 ] && echo "start $prog finshed" fi}stop (){ if [ -f $lockfile ];then rm -f $lockfile [ $? -eq 0 ] && echo "stop $prog finshed" else echo "$prog is not running" fi}status () { if [ -f $lockfile ];then echo "$prog is running" else echo "$prog is stopped" fiusage () { echo "Useage: $lockfile { start|stop|restart|status}"}case $1 instart) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) usageesac[root@centous1 lianxi]# bash +x testdir3.sh startstart testdir3.sh finshed [root@centous1 lianxi]# bash +x testdir3.sh stopstop testdir3.sh finshed [root@centous1 lianxi]# vim testdir3.sh[root@centous1 lianxi]# bash +x testdir3.sh stoptestdir3.sh is not running [root@centous1 lianxi]# bash +x testdir3.sh stUseage: /home/soft/testdir3.sh { start|stop|restart|status}
函数返回值:
函数执行结果返回值: (1)使用echo或printf命令进行输出; (2)函数体重调用的命令的执行结果;
函数的退出状态码:
(1)默认取决于函数体重执行的最后一条命令的退出状态码; (2)自定义:return
函数可以接收参数:
传递参数给函数: 在函数体中,可以使用$1,$2...医用传递给函数的参数;还可以在函数 中使用$* $@引用所有参数,$#引用传递的参数个数 在调用函数时,在函数名后面以空白符分隔给定参数列表即可,例如,arg1 arg2
再这里应该注意的是,一个脚本中需要使用$1,$2…时,注意,如果其中有函数,那么函数会直接调用,而不是经过脚本之后再调用。
示例;添加10个用户, 添加用户的功能使用函数实现,用户名作为参数传递给函数;
#!/bin/bash##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} finshed" elif [ $retval -eq 5 ];then echo "user ${1}${i} exists." else echo "Unkown Error" fidone[root@centous1 lianxi]# bash -x userAD.sh abc+ for i in '{1..10}'+ addusers abc1 + id abc1 + useradd abc1 + retval=0+ return 0+ '[' 0 -eq 0 ']'+ echo 'Add user abc1 finshed'..... ..... [root@centous1 lianxi]# bash -x userAD.sh abc+ for i in '{1..10}'+ addusers abc1 + id abc1 + return 5+ retval=5+ '[' 5 -eq 0 ']'+ '[' 5 -eq 5 ']'+ echo 'user abc1 exists.'.... ....
变量作用域:
局部变量:
作用域的函数的生命周期;在函数结束时被自动销毁;
定义局部变量的方法:local VARIABLE=VALUE
本地变量:作用域是运行脚本的shell进程的生命周期;因此,其作用域是脚本程序文件。
用例子来说明
#!/bin/bash#name=tomsetname(){ name=jarry echo "$name"} setnameecho "$name"~ [root@centous1 lianxi]# bash -x 123.sh+ name=tom + setname + name=jarry + echo jarry jarry + echo jarry jarry#!/bin/bash#name=tomsetname(){ local name=jarry echo "$name"} setnameecho "$name"[root@centous1 lianxi]# bash -x 123.sh+ name=tom + setname + local name=jarry + echo jarry jarry + echo tom tom
原创文章,作者:forest,如若转载,请注明出处:http://www.178linux.com/39023