bash脚本编程:之case语句
 
条件测试:
0: 成功
1-255: 失败
 
命令:
[ expression ]
[[ expression ]]
test expression
 
exPression:
整数测试:
-gt, -ge, -lt, -le, -eq, -ne
字符串:
>, < , >=, <=, ==, !=, =~, -z, -n
文件:
-e, -f, -d, -b, -c, -h, -S, -s, -a, -p, -r, -w, -x
 
多分支的if语句:
if boolean_expression1; then
suite1
elif boolean_expression2; then
suite2
...
elif boolean_expressionn; then
suiten
else
else_suite
fi
 
练习:写一个脚本,接受如此格式
script.sh {start|stop|restart|status}
1、如是start,那么创建/var/lock/subsys/script.sh,显示启动成功;
2、如果参数是stop,则删除/var/lock/subsys/script.sh,显示停止成功
3、如果restart,则删除,再创建,显示成功;
4、如果status, 如果文件存在,则显示running,否则,显示stopped
 
#!/bin/bash
#
myService=`basename $0`
lockFile="/var/lock/subsys/$myService"
 
[ $# -lt 1 ] && echo "Usage: $myService {start|stop|restart|status}" && exit 4
 
if [ "$1" == 'start' ]; then
        touch $lockFile
        echo "Starting $myService OK"
elif [ "$1" == 'stop' ]; then
        rm -f $lockFile
        echo "Stopping $myService OK"
elif [ "$1" == 'restart' ]; then
        rm -f $lockFile
        touch $lockFile
        echo "Restarting $myService OK"
elif [ "$1" == 'status' ]; then
        if [ -f $lockFile ]; then
                echo "$myService is running"
        else
                echo "$myService is stopped"
        fi
else
        echo "Usage: $myService {start|stop|restart|status}"
        exit 3
fi
 
 
case语句的语法格式:
case expression in
pattern1)
suite1 
;;
pattern2)
suite2
;;
...
patternn)
suiten
;;
*)
other_suite
;;
esac
 
上述脚本的case实现:
 
#!/bin/bash
#
myService=`basename $0`
lockFile="/var/lock/subsys/$myService"
 
[ $# -lt 1 ] && echo "Usage: $myService {start|stop|restart|status}" && exit 4
 
case $1 in
'start')
        touch $lockFile
        echo "Starting $myService OK"
        ;;
'stop')
        rm -f $lockFile
        echo "Stopping $myService OK"
        ;;
'restart')
        rm -f $lockFile
        touch $lockFile
        echo "Restarting $myService OK"
        ;;
'status')
        if [ -f $lockFile ]; then
                echo "$myService is running"
        else
                echo "$myService is stopped"
        fi
        ;;
*)
        echo "Usage: $myService {start|stop|restart|status}"
        exit 3
        ;;
esac
 
 
case中各pattern可以使用模式:
a|b: a或者b
*:匹配任意长度的任意字符;
?:匹配任意单个字符;
[-]:范围匹配
 
[a-z])
[0-9])
 
练习:写一个简单脚本
1、提示用户输入一个任意字符;
2、能判断此字符是数字、字母或特殊字符;
 
#!/bin/bash
#
while true; do
read -p "Enter a char: " char
 
[[ "$char" == 'quit' ]] && break
 
case $char in
[a-z])
        echo "letter"
        ;;
[0-9])
        echo "digit"
        ;;
*)
        echo "special"
        ;;
esac
done
 
 
练习:写一个脚本,能对/etc/目录进行打包备份,备份位置为/backup/etc-日期.后缀
1、显示如下菜单给用户:
xz) xz compress
gzip) gzip compress
bip2) bzip2 compress
2、根据用户指定的压缩工具使用tar打包压缩;
3、默认为xz;输入错误则需要用户重新输入;
 
#!/bin/bash
#
[ -d /backup ] || mkdir /backup
 
cat << EOF
Plz choose a compress tool:
 
xz) xz compress
gzip) gzip compress
bip2) bzip2 compress
EOF
 
while true; do
  read -p "Your option: " option
  option=${option:-xz}
 
  case $option in
  xz)
    compressTool='J'
    suffix='xz'
    break ;;
  gzip)
    compressTool='z'
    suffix='gz'
    break ;;
  bzip2)
    compressTool='j'
    suffix='bz2'
    break ;;
  *)
    echo "wrong option." ;;
  esac
done
 
tar ${compressTool}cf /backup/etc-`date +%F-%H-%M-%S`.tar.$suffix /etc/*
 
练习:写一个脚本,完成如下功能
说明:此脚本能够为指定网卡创建别名,指定地址;使用格式:mkethalias.sh -v|--verbose -i|--interface ethX
1|-i选项用于指定网卡;
2、如果网卡存在:在命令行,请用户指定一个别名;
3、让用户指定IP和掩码;
4、用户可以同时使用-v或--verbose选项:如果使用了,则在配置完成后,显示配置结果;否则,则不予显示;
 
#!/bin/bash
#
debug=0
 
while [ $# -ge 1 ]; do
  case $1 in
  -i|--interface)
    ethcard="$2"
    shift 2 ;;
  -v|--verbose)
    debug=1
    shift
    ;;
  *)
    echo "Wrong options or arguments."
    echo "Usage: `basename $0` [-v|--verbose] -i|--interface Interface"
    shift $#
    ;;
  esac
done
 
# echo "Interface: $ethcard , Verbose Flag: $debug "
 
! ifconfig $ethcard &> /dev/null && echo "No this interface..." && exit 3
 
read -p "Enter an alias: " ethAlias
 
read -p "Enter IP: " ipAddr
 
read -p "Mask: " netMask
 
ifconfig $ethAlias $ipAddr netmask $netMask
 
[ $debug -eq 1 ] && ifconfig $ethAlias
 
 
bash脚本编程之函数
模块化编程的工具
 
函数:function,功能组件
 
可被调用:函数有函数名
函数出现的地方,而自动被替换成函数定义的代码
 
函数定义
 
 
语法:
FuncName() {
函数体
}
 
function FuncName {
函数体
}
 
 
函数有两种返回值:
正常返回的数据:
函数中的打印语句,如echo或print
函数中命令的执行结果
执行状态返回值:
取决于函数中执行的最后一条语句
自定义:return N
 
函数可以接受参数:
在函数体可以使用类似脚本调用位置参数一样的参数
$1, $2, ...
$#
$*, $@
 
 
#!/bin/bash
#
function ShowUserInfo {
  [ $# -lt 1 ] && return 6
  grep "^$1\>" /etc/passwd | cut -d: -f3,7
}
 
function main {
while true; do
  read -p "Plz enter a user name: " userName
 
  if [ "$userName" == 'quit' ]; then
        echo "Quit"
        exit 0
  fi
 
  if ! id $userName &> /dev/null; then
    echo "No such user, please again."
    continue
  fi
  ShowUserInfo $userName
done
}
 
main
 
 
练习:写一个脚本,完成如下功能
1、显示如下菜单
disk) show disk info
mem) show memory info
cpu) show cpuinfo
2、显示用户选定的内容;
 
#!/bin/bash
#
ShowMenu() {
cat << EOF
disk) show disk info
mem) show memory info
cpu) show cpuinfo
EOF
}
 
main() {
ShowMenu
read -p "Plz choose an option: " option
case $option in
disk)
   df -h
   ;;
mem)
   free -m
   ;;
cpu)
  cat /proc/cpuinfo
  ;;
*)
  echo "Wrong option"
esac
}
 
main
 
如果在函数中使用变量:变量作用域
在函数中使用了在主程序中声明的变量,重新赋值会直接修改主程序中的变量;
如果不期望函数与主程序中的变量冲突,函数中使用变量都用local修饰;即使用局部变量;
在函数中使用了在主程序中没有声明的变量,在函数执行结束后即被撤消,无论是否使用local修饰符;
 
 
如果想把脚本的全部位置参数,统统传递给脚本中某函数使用,怎么办?
使用$*传递
 
 
 
 
 
练习:写一个脚本,判定172.16.0.0网络内有哪些主机在线,在线的用绿色显示,不在线的用红色显示;要求,编程中使用函数;
 
C类网:ping NetAdd.HostAdd
B类网:ping NetAadd.NetAadd.HostAdd.HostAdd
 
CnetPing() {
for i in {1..254}; do
ping -c 1 -w 1 $1.$i
}
 
# CnetPing 192.168.10
 
BnetPing() {
for j in {0.255}; do
CnetPing $1.$j
done
}
 
AnetPing() {
for m in {0..255}; do
BnetPing $1.$m
done
}
 
netType=`echo $1 | cut -d'.' -f1`
 
if [ $netType -gt 0 -a $netType -le 126 ]; then
AnetPing $1
elif [ $netType -ge 128 -a $netType -le 191 ]; then
  BnetPing $1
elif [ $netType -ge 192 -a $netType -le 223 ]; then
CnetPing $1
else
echo "Wrong"
exit 3
fi
 
 
 
练习:写一个脚本,完成如下功能(使用函数):
1、提示用户输入一个可执行命令;
2、获取这个命令所依赖的所有库文件(使用ldd命令);
3、复制命令至/mnt/sysroot/对应的目录中
解释:假设,如果复制的是cat命令,其可执行程序的路径是/bin/cat,那么就要将/bin/cat复制到/mnt/sysroot/bin/目录中,如果复制的是useradd命令,而useradd的可执行文件路径为/usr/sbin/useradd,那么就要将其复制到/mnt/sysroot/usr/sbin/目录中;
4、复制各库文件至/mnt/sysroot/对应的目录中,其要求命令;
 
#!/bin/bash
#
target=/mnt/sysroot
 
clearCmd() {
  if which $cmd &> /dev/null; then
        cmdPath=`which --skip-alias $cmd`
  else
        echo "No such command"
        return 5
  fi
}
 
cmdCopy() {
        cmdDir=`dirname $1`
        [ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir}
        [ -f ${target}${1} ] || cp $1 ${target}${cmdDir}
}
 
libCopy() {
        for lib in `ldd $1 | grep -o "/[^[:space:]]\{1,\}"`; do
                libDir=`dirname $lib`
                [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
                [ -f ${target}${lib} ] || cp $lib ${target}${libDir}
        done
}
 
while true; do
  read -p "Enter a command: " cmd
  if [ "$cmd" == 'quit' ] ;then
        echo "quit"
        exit 0
  fi
  clearCmd $cmd
  [ $? -eq 5 ] && continue
 
  cmdCopy $cmdPath
  libCopy $cmdPath
done
 
 
 
 
练习:写一个脚本,完成如下功能(使用函数):
1、脚本使用格式:
mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /path/to/somefile
2、如果文件事先不存在,则创建;且前几行内容如下所示:
#!/bin/bash
# Description: script description
# Author: script author
#
3、如果事先存在,但不空,且第一行不是“#!/bin/bash”,则提示错误并退出;如果第一行是“#!/bin/bash”,则使用vim打开脚本;把光标直接定位至最后一行
4、打开脚本后关闭时判断脚本是否有语法错误
如果有,提示输入y继续编辑,输入n放弃并退出;
如果没有,则给此文件以执行权限;
 
arguParse() {
 
}
 
 
 
 
 
 
 

最新文章

  1. .NET (一)委托第一讲:什么是委托
  2. NGUI BUG /各种坑
  3. Tomcat 服务器版本的区别以及下载与安装
  4. python的方法总结:
  5. service httpd restart失败解决方法(小记)
  6. Android:WebView(慕课网)
  7. iOS9新特性-3D Touch
  8. [Python Study Notes]磁盘信息和IO性能
  9. android小程序之幸运菜谱
  10. 【SSH系列】Hibernate映射 -- 一对多关联映射
  11. vue(5)—— vue的路由插件—vue-router 常用属性方法
  12. Python课程学习总结
  13. C#网络请求与JSON解析
  14. java.sql.SQLException: Field &#39;id&#39; doesn&#39;t have a default value
  15. angular5 @viewChild @ContentChild ElementRef renderer2
  16. Phonics 自然拼读法 s,a,t,i,p,n Teacher:Lamb
  17. websocket与canvas[转]
  18. php的几种算法(转载)
  19. HDU 2825 Wireless Password
  20. The superclass &quot;javax.servlet.http.HttpServlet&quot; was not found on the Java Build Path问题的解决

热门文章

  1. hdu1693Eat the Trees(插头dp)
  2. python 扩展注册功能装饰器举例
  3. angularJs 指令调用父controller某个方法
  4. jsp学习与提高(一)——JSP生命周期、三大指令及动作
  5. centos 创建 logrotate 进行日志分割
  6. 详解javascript中的this对象
  7. Linux —— ps命令
  8. mirror与repository的关系
  9. python 7 dict和set
  10. Spring 顾问