Shell编程入门(第二版)(下)
流程控制语句
三、select/in[较少用]
格式:
- select [变量] in [关键字]
- do
- command 1
- ... ...
- command n
- done
- #select把关键字中的每一项做成类似表单,以交互的方式执行do和done之间的命令
示例-select.sh
- #!/bin/bash
- # Show select usage
- echo "What's your favorate OS?"
- select var in "Linux" "Windows" "UNIX" "Other"
- do
- break
- done
- echo "You have selected $var"
四、case/esac
格式:
- case 变量 in
- 字符串1)
- 命令列表1
- ;;
- ...
- 字符串n)
- 命令列表n
- ;;
- esac
示例-case.sh
- #!/bin/bash
- # Show Usage for case/esac
- echo "*********************************"
- echo "Please select a oprator as below:"
- echo "C ... copy"
- echo "D ... delete"
- echo "B ... backup"
- echo "*********************************"
- read op
- case $op in
- C)
- echo "copy...."
- ;;
- D)
- echo "delete...."
- ;;
- B)
- echo "backup..."
- ;;
- *)
- echo "Unknow operator!"
- exit 1
- esac
示例-select.case
- #!/bin/bash
- # A test shell script for select and case
- echo "a is 5, b is 3, please select your method"
- a=5
- b=3;
- select var in "a+b" "a-b" "a*b" "a/b"
- do
- break
- done
- case $var in
- "a+b")
- echo "a+b="`expr $a + $b `
- ;;
- "a-b")
- echo "a-b="`expr $a - $b`
- ;;
- "a*b")
- echo "a*b="`expr $a \* $b`
- ;;
- "a/b")
- echo "a/b="`expr $a / $b`
- ;;
- *)
- echo "input error..."
- exit 1
- esac
实例-/etc/rc.d/init.d/httpd部分源代码
- # See how we were called.
- case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- ;;
- restart)
- stop
- start
- ;;
- condrestart|try-restart)
- if status -p ${pidfile} $httpd >&/dev/null; then
- stop
- start
- fi
- ;;
- force-reload|reload)
- reload
- ;;
- graceful|help|configtest|fullstatus)
- $apachectl $@
- RETVAL=$?
- ;;
- *)
- echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}"
- RETVAL=2
- esac
五、while
格式:
- while 条件 #无限:while true
- do
- 命令
- done
示例-while.sh
- #!/bin/bash
- # A usage for while
- num=1
- while [ $num -le 10 ]
- do
- echo $(expr $num \* $num)
- let num++
- done
示例-useradd.sh
- #!/bin/bash
- # A shell script to add user(s)
- #echo 123456 | passwd --stdin xiaofang #用非交互方式设置xiaofang的密码
- echo -n "Plese input the user name: "
- read username
- echo -n "Plese input the sum users: "
- read sum
- num=1
- while [ $num -le $sum ]
- do
- /usr/sbin/useradd "$username$num"
- if [ $? -ne 0 ]
- then
- echo "user: $username already exists."
- exit 1
- fi
- let num++
- done
- echo -n "Please input the passwd for this users: "
- read passwd
- i=1
- while [ $i -le $sum ]
- do
- echo $passwd | /usr/bin/passwd --stdin "$username$i"
- let i++
- done
示例-userdel.sh
- #!/bin/bash
- # A shell script for delete user(s)
- echo -n "Please input the username: "
- read username
- echo -n "Please input the user number: "
- read num
- i=1
- while [ $i -le $num ]
- do
- /usr/sbin/userdel -r $username$i
- if [ $? -ne 0 ]
- then
- echo "User: $username$i is not exists."
- let i++
- continue
- fi
- let i++
- done
六、until
格式:
- until 条件
- do
- 命令
- done
- #until类似while循环,不同的是until是条件返回值为假时才继续执行。
示例-until.sh
- #!/bin/bash
- # A script to show until usage.
- echo "Please input Y/y to stop..."
- read input
- until [ "$input" = "Y" ] || [ "$input" = "y" ]
- do
- echo "input error, input again!"
- read input
- done
七、跳出循环:break和continue
break:跳出整个循环
continue:跳过本次循环,进行下次循环
示例-break_continue.sh
- #!/bin/bash
- # A test shell script for break&continue
- while true
- do
- echo "*****************************"
- echo "Please have a select as blow:"
- echo "1 Copy"
- echo "2 Delete"
- echo "3 Backup"
- echo "4 Quit***********************"
- read op
- case $op in
- "1")
- echo "$op is Copy"
- ;;
- "2")
- echo "$op is Delete"
- ;;
- "3")
- echo "$op is Backup"
- ;;
- "4")
- echo "Exit..."
- break
- ;;
- "*")
- echo "Invalide selectino, please select again..."
- continue
- ;;
- esac
- done
八、shift指令
参数左移,每执行一次,参数序列顺次左移一个位置,$#的值减1, 用于分别处理每个参数,移出去的参数不再可用
示例-shift.sh
- #!/bin/bash
- # A test shell script for shift
- if [ $# -lt 1 ]
- then
- echo "No enough parameters"
- exit 1
- fi
- num=0
- while [ $# -gt 0 ]
- do
- echo '$1 is '$1
- let num++
- shift
- done
- echo $num
函数应用
实例-/etc/rc.d/init.d/httpd中的start源代码
一、函数的定义:
- 函数名 ()
- {
- 命令序列
- }
二、函数的调用:不带()
函数名 参数1 参数2 ... 参数n
实例-调用
三、函数中的变量:
变量均为全局变量,没有局部变量
四、函数中的参数:
调用函数时,可以传递参数,在函数中用$1、$2...来引用
示例-function.sh
- #!/bin/bash
- # A test shell script for function
- # function
- Help(){
- echo "Usage: sh function \$1 \$2 \$3"
- }
- Display(){
- echo "three argument: $1 $2 $3"
- }
- # main
- if [ $# -ne 3 ]
- then
- Help
- else
- echo "Think you for your input"
- Display $1 $2 $3
- fi
Shell 脚本调试
sh -x script 这将执行该脚本并显示所有变量的值。
sh -n script 不执行脚本只是检查语法的模式,将返回所有语法错误。
最佳实践-命令最好使用绝对路径
一个脚本能够执行-
1.对脚本有rx权限,只有r,可以使用sh执行
2.对脚本所在目录至少有rx权限
拓展实例-setuid.sh
- #!/bin/bash
- # After the system installed, please check setuid files first for security
- # mkdir /backup
- # find / -perm -4000 -o -perm -2000 > /backup/setuid.list
- /bin/find / -perm -4000 -o -perm -2000 > /tmp/setuid.list 2> /dev/null
- for var in `/bin/cat /tmp/setuid.list`
- do
- /bin/grep $var /backup/setuid.list > /dev/null 2> /dev/null
- if [ $? -ne 0 ]
- then
- echo "$var is not in /backup/setuid.list, It's danger!"
- fi
- done