第18章.控制流结构
时间:2008-09-27 来源:zwc0819
1.简单的if语句
[root@test zwc]# cat iftest
#!/bin/sh
#iftest
if [ "10" -lt "12" ]
then echo "Yes, 10 is less than 12"
fi
[root@test zwc]# ls -l iftest
-rw-r--r-- 1 root root 78 9月 20 02:04 iftest
[root@test zwc]# chmod 750 iftest
[root@test zwc]# ./iftest
Yes, 10 is less than 12
2.测试变量值
[root@test zwc]# cat iftest2
#!/bin/sh
#if test2
echo -n "Enter your name :"
read NAME
if [ "$NAME" = "" ] ; then
echo "You did not enter any information"
[root@test zwc]# chmod 750 iftest2
[root@test zwc]# ./iftest2
Enter your name :
You did not enter any information
[root@test zwc]# ./iftest2
Enter your name :zwc
11.变量设置测试
[root@test zwc]# cat ifeditor
#!/bin/sh
#ifeditor
if [ -z $EDITOR ]; then
#the variable hao not been set
echo "Your EDITOR envitonment is not set"
else
#let's see what it is
echo "Using $EDITOR as the default editor"
fi
[root@test zwc]# chmod 750 ifeditor
[root@test zwc]# ./ifeditor
Your EDITOR envitonment is not set
12.检测运行脚本的用户
[root@test zwc]# cat ifroot
#!/bin/sh
#ifroot
if [ "$LOGNAME" != "root" ]
#if the user is not root
then
echo "You need to be root to run this script"
exit 1
else
#yes it is root
echo "Yes indeed you are $LOGNAME processed"
fi
#normal processing statements go here
[root@test zwc]# chmod 750 ifroot
[root@test zwc]# ./ifroot
Yes indeed you are root processed
[root@test zwc]# cat ifroot
#!/bin/sh
#ifroot
if [ "$LOGNAME" != "root" ]
#if the user is not root
then
echo "You need to be root to run this script"
exit 1
else
#yes it is root
echo "Yes indeed you are $LOGNAME processed"
fi
#normal processing statements go here
./ifeditor
[root@test zwc]# ./ifroot
Yes indeed you are root processed
Your EDITOR envitonment is not set
[root@test zwc]# cat ifroot
#!/bin/sh
#ifroot
if [ "$LOGNAME" != "root" ]
#if the user is not root
then
echo "You need to be root to run this script"
exit 1
else
#yes it is root
./ifeditor
fi
[root@test zwc]# ./ifroot
Your EDITOR envitonment is not set
13.将脚本参数传递给系统命令
[root@test zwc]# cat ifdirec
#!/bin/sh
#ifdirec
#assigning $1 to DIRECTORY variable
DIRECTORY=$1
if [ "`ls -A $DIRECTORY`" = "" ] ; then
#if it'a an empty string, then it's empty
echo "$DIRECTORY is indeed empty"
else
#otherwise it is not
echo "$DIRECTORY is not empty"
fi
[root@test zwc]# chmod 750 ifdirec
[root@test zwc]# ./ifdirec
is not empty
[root@test zwc]# cat ifdirec2
#!/bin/sh
#ifdirec2
DIRECTORY=$1
if [ -z "`ls -a $DIRECTORY`" ]
then
echo "$DIRECTORY is indeed empty"
else
echo "$DIRECTORY is no empty"
fi
[root@test zwc]# chmod 750 ifdirec2
[root@test zwc]# ./ifdirec2
is no empty
14.null:命令用法
[root@test zwc]# vi ifdirectory
[root@test zwc]# cat ifdirectory
#!/bin/sh
#ifdirectory
DIRECTORY=$1
if [ "`ls -A $DIRECTORY`" = "" ]
then
echo "$DIRECTORY is indeed empty"
else : # do nothing
fi
[root@test zwc]# chmod 750 ifdirectory
[root@test zwc]# ./ifdirectory
15.测试目录创建结果
18.4case语句
18.4.1 简单的case语句
[root@test zwc]# vi caseselect
[root@test zwc]# cat caseselect
#!/bin/sh
#caseselect
echo -n "enter a number from 1 to 5 :"
read ANS
case $ANS in
1) echo "you select 1"
;;
2) echo "you select 2"
;;
3) echo "you select 3"
;;
4) echo "you select 4"
;;
5) echo "you select 5"
;;
*)echo "`basename $0`: This is not between 1 and 5"
exit 1
;;
esac
[root@test zwc]# chmod 750 caseselect
[root@test zwc]# ./caseselect
enter a number from 1 to 5 :2
you select 2
[root@test zwc]# ./caseselect
enter a number from 1 to 5 :abc
caseselect: This is not between 1 and 5
18.4.2 对匹配模式使用|
[root@test zwc]# vi caseterm
[root@test zwc]# cat caseterm
#!/bin/sh
#caseterm
echo "choices are.. vt100, vt102,vt220"
echo -n "enter your terminal type :"
read TERMINAL
case $TERMINAL in
vt100|vt102) TERM=vt100
;;
vt220) TERM=vt220
;;
*)echo "`basename $0` : Unknown respone"
echo "setting it to vt100 anyway, so there"
TERM=vt100
;;
esac
export TERM
echo "Your terminal is set to $TERM"
[root@test zwc]# chmod 750 caseterm
[root@test zwc]# ./caseterm
choices are.. vt100, vt102,vt220
enter your terminal type :vt102
Your terminal is set to vt100
[root@test zwc]# ./caseterm
choices are.. vt100, vt102,vt220
enter your terminal type :vt220
Your terminal is set to vt220
[root@test zwc]# ./caseterm
choices are.. vt100, vt102,vt220
enter your terminal type :vt800
caseterm : Unknown respone
setting it to vt100 anyway, so there
Your terminal is set to vt100
18.4.3 提示键入y或n
[root@test zwc]# vi caseans
[root@test zwc]# cat caseans
#!/bin/sh
#caseans
echo -n "Do you wish to proceed [y..n] :"
read ANS
case $ANS in
y|Y|yes|Yes) echo "yes is selected"
;;
n|N) echo "no is selected"
exit 0 #no error so only use exit 0 to terminal
;;
*) echo "`basename $0` :Unknown response"
exit 1
;;
esac
#if we are here then a y|Y|yes|Yes was selected only.
[root@test zwc]# chmod 750 caseans
[root@test zwc]# ./caseans
Do you wish to proceed [y..n] :Y
yes is selected
[root@test zwc]# ./caseans
Do you wish to proceed [y..n] :n
no is selected
[root@test zwc]# vi caseans
[root@test zwc]# ./caseans
Do you wish to proceed [y..n] :dfg
caseans :Unknown response
18.4.4 case与命令参数传递
18.5 for循环
18.5.1简单的for循环
[root@test zwc]# cat for_i
#!/bin/sh
#for_i
for loop in 1 2 3 4 5
do
echo $loop
done
[root@test zwc]# chmod 750 for_i
[root@test zwc]# ./for_i
1
2
3
4
5
18.5.4 对for循环使用参数
[root@test zwc]# cat forparam2
#!/bin/sh
#forparam2
for params
do
echo "You supplied $params as a command line option"
done
[root@test zwc]#chmod 750 forparams2
[root@test zwc]# ./forparam2 myfile myfile2 myfile3
You supplied myfile as a command line option
You supplied myfile2 as a command line option
You supplied myfile3 as a command line option
[root@test zwc]# cat forparam2
#!/bin/sh
#forparam2
for params in "$@"
do
echo "You supplied $params as a command line option"
done
[root@test zwc]# ./forparam2 myfile myfile2 myfile3
You supplied myfile as a command line option
You supplied myfile2 as a command line option
You supplied myfile3 as a command line option
[root@test zwc]# vi forfind
[root@test zwc]# cat forfind
#!/bin/sh
#forfind
for loop
do
find / -name $loop -print
done
[root@test zwc]# chmod 750 forfind
[root@test zwc]# ./forfind passwd
/etc/pam.d/passwd
/etc/passwd
/usr/bin/passwd
/usr/share/doc/nss_ldap-226/pam.d/passwd
18.5.5 使用for循环连接服务器
[root@test zwc]# vi forping
[root@test zwc]# cat forping
#!/bin/sh
#forping
HOSTS="itserv dnssevr acctsmain ladpd ladware"
for loop in $HOSTS
do
ping -c 2 $loop
done
[root@test zwc]# chmod 750 forp
forparam2 forping
[root@test zwc]# chmod 750 forping
[root@test zwc]# ./forping
ping: unknown host itserv
ping: unknown host dnssevr
ping: unknown host acctsmain
ping: unknown host ladpd
ping: unknown host ladware
[root@test zwc]# ping www.qq.com
ping: unknown host www.qq.com
[root@test zwc]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.10.11.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
[root@test zwc]# service network restart
正在关闭接口 eth0: [ 确定 ]
关闭环回接口: [ 确定 ]
设置网络参数: [ 确定 ]
弹出环回接口: [ 确定 ]
弹出界面 eth0: [ 确定 ]
[root@test zwc]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.10.11.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
default 10.10.11.138 0.0.0.0 UG 0 0 0 eth0
[root@test zwc]# ping www.qq.com
PING www.qq.com (222.73.78.201) 56(84) bytes of data.
64 bytes from 222.73.78.201: icmp_seq=0 ttl=54 time=31.8 ms
64 bytes from 222.73.78.201: icmp_seq=1 ttl=54 time=27.4 ms
64 bytes from 222.73.78.201: icmp_seq=2 ttl=54 time=38.9 ms
--- www.qq.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 27.451/32.769/38.968/4.747 ms, pipe 2
[root@test zwc]# vi forping
[root@test zwc]# cat forping
#!/bin/sh
#forping
HOSTS="itserv dnssevr acctsmain ladpd ladware"
for loop in $HOSTS
do
ping -c 2 $loop
done
[root@test zwc]# ./forping
PING www.qq.com (222.73.78.201) 56(84) bytes of data.
64 bytes from 222.73.78.201: icmp_seq=0 ttl=54 time=29.4 ms
64 bytes from 222.73.78.201: icmp_seq=1 ttl=54 time=28.6 ms
--- www.qq.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 28.698/29.088/29.478/0.390 ms, pipe 2
PING www.cache.split.netease.com (220.181.28.54) 56(84) bytes of data.
64 bytes from 220.181.28.54: icmp_seq=0 ttl=53 time=40.0 ms
64 bytes from 220.181.28.54: icmp_seq=1 ttl=53 time=36.2 ms
--- www.cache.split.netease.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 36.218/38.148/40.079/1.940 ms, pipe 2
PING jupiter.sina.com.cn (61.172.201.194) 56(84) bytes of data.
64 bytes from 61.172.201.194: icmp_seq=0 ttl=247 time=4.93 ms
64 bytes from 61.172.201.194: icmp_seq=1 ttl=247 time=5.00 ms
--- jupiter.sina.com.cn ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 4.931/4.966/5.001/0.035 ms, pipe 2
18.5.6 使用for循环备份文件
18.5.7 多文件转换
18.5.8 多sed删除操作
18.5.9 循环计数
18.5.10 for循环和本地文档
18.5.11 for循环嵌入
18.6 until循环
18.6.1简单的until循环
[root@test zwc]# vi until_who
[root@test zwc]# cat until_who
#!/bin/sh
#until_who
IS_ROOT=`who | grep root`
until [ "$IS_ROOT" ]
do
sleep 5
done
echo "Watch it. root in" | mail zwc
[root@test zwc]# chmod 750 until_who
[root@test zwc]# ./until_who
[root@test /]# ls
abc.txt dev initrd media opt sbin swap usr
bin etc lib misc proc selinux sys var
boot home lost+found mnt root srv tmp zwc
[root@test /]# cd var
[root@test var]# ls
account crash empty gdm local log nis preserve spool tux yp
cache db ftp lib lock mail opt run tmp www
[root@test var]# cd spool/
[root@test spool]# ls
anacron clientmqueue cups mail repackage squid vbox
at cron lpd mqueue samba up2date
[root@test spool]# cd mail
[root@test mail]# ls
oracle root zwc
[root@test mail]# cat zwc
From root@test Wed Sep 24 20:52:34 2008
Return-Path: <root@test>
Received: from test (localhost.localdomain [127.0.0.1])
by test (8.13.1/8.13.1) with ESMTP id m8OCqYgw003050
for <zwc@test>; Wed, 24 Sep 2008 20:52:34 +0800
Received: (from root@localhost)
by test (8.13.1/8.13.1/Submit) id m8OCqYVg003020
for zwc; Wed, 24 Sep 2008 20:52:34 +0800
Date: Wed, 24 Sep 2008 20:52:34 +0800
From: root <root@test>
Message-Id: <200809241252.m8OCqYVg003020@test>
To: zwc@test
Watch it. root in
18.6.3 监视磁盘空间
[root@test zwc]# cat until_mon
#!/bin/sh
#until_mon
#get percent column and srtip off header row from df
LOOK_OUT=`df | grep /boot | awk '{print $5}' | sed 's/%//g'`
echo $LOOK_OUT
until [ "$LOOK_OUT" -gt "5" ]
do
echo "Filesystem..logs is nearly full" | mail zwc
exit 0
done
[root@test zwc]# chmod 750 until_mon
[root@test zwc]# ./until_mon
10
[root@test zwc]#cd /var/spool/mail
[root@test mail]#cat zwc
From root@test Wed Sep 24 23:39:12 2008
Return-Path: <root@test>
Received: from test (localhost.localdomain [127.0.0.1])
by test (8.13.1/8.13.1) with ESMTP id m8OFdC0X029900
for <zwc@test>; Wed, 24 Sep 2008 23:39:12 +0800
Received: (from root@localhost)
by test (8.13.1/8.13.1/Submit) id m8OFdCiF029880
for zwc; Wed, 24 Sep 2008 23:39:12 +0800
Date: Wed, 24 Sep 2008 23:39:12 +0800
From: root <root@test>
Message-Id: <200809241539.m8OFdCiF029880@test>
To: zwc@test
Filesystem..logs is nearly full
18.7 while循环
18.7.1 简单的while循环
[root@test zwc]# cat whilecount
#!/bin/sh
#whilecount
COUNTER=0
while [ $COUNTER -lt 5 ]
do
#add one to the counter
COUNTER=`expr $COUNTER + 1`
echo $COUNTER
done
[root@test zwc]# chmod 750 whilecount
[root@test zwc]# ./whilecount
1
2
3
4
5
18.7.2 使用while循环读键盘输入
18.7.3 使用while循环从文件中读取数据
[root@test zwc]# cat name.txt
a:b:c
d:e:f
h:i:j
[root@test zwc]# cat while
[root@test zwc]# cat whileread
#!/bin/sh
#whileread
while read LINE
do
echo $LINE
done < name.txt
[root@test zwc]# chmod 750 whileread
[root@test zwc]#
[root@test zwc]# ./whileread
a:b:c
d:e:f
h:i:j
18.7.4 使用IFS读文件
[root@test zwc]# vi whilereadifs
[root@test zwc]# cat whilereadifs
#!/bin/sh
#whilereadifs
#save the setting of IFS
SAVEDIFS=$IFS
#assign new seprarator to IFS
IFS=:
while read NAME DEPT ID
do
echo -e "$NAME\t $DEPT\t $ID"
done < name.txt
# restore the setting of IFS
IFS=$SAVEDIFS
[root@test zwc]# chmod 750 whilereadifs
[root@test zwc]# ./whilereadifs
a b c
d e f
h i j
18.7.5 带有条件测试的文本处理
root@test zwc]# cat whileread_file
#/bin/sh
#whileread_file
#initialise variables
SAVEDIFS=$IFS
IFS=:
HOLD_FILE=hold_file
NAME_MATCH="James Lenod"
INPUT_FILE=names.txt
#creat a new HOLD_FILE each time, in case script is continuously run >$HOLD_FILE
while read NAME DEPT ID
do
#echo all information into holdfile with redrection
echo $NAME $DEPT $ID >>$HOLD_FILE
#is it a match ???
if [ "$NAME" = "$NAME_MATCH" ]; then
#yes then nice exit
echo "all entries up to and including $NAME_MATCH are in $HOLD_FILE"
exit 0
fi
done < $INPUT_FILE
#restore IFS
IFS=$SAVEDIFS
[root@test zwc]# chmod 750 whileread_file
[root@test zwc]# ./whileread_file
[root@test zwc]# ./whileread_file
all entries up to and including James Lenod are in hold_file
18.8 使用break和continue控制循环
188.1 break
18.8.2 跳出case语句
[root@test zwc]# cat breakout
#!/bin/sh
# breakout
# while : means loop forever
while :
do
echo -n "Enter any namber [1..5] :"
read ANS
case $ANS in
1|2|3|4|5) echo "great you entered a number between 1 and 5"
;;
*)echo "Wrong number..bye"
;;
esac
done
[root@test zwc]# chmod 750 breakout
[root@test zwc]# ./breakout
Enter any namber [1..5] :1
great you entered a number between 1 and 5
Enter any namber [1..5] :5
great you entered a number between 1 and 5
Enter any namber [1..5] :9
Wrong number..bye
Enter any namber [1..5] :1
great you entered a number between 1 and 5
Enter any namber [1..5] :2
(陷入死循环)
[root@test zwc]# vi breakout
[root@test zwc]# cat breakout
#!/bin/sh
# breakout
# while : means loop forever
while :
do
echo -n "Enter any namber [1..5] :"
read ANS
case $ANS in
1|2|3|4|5) echo "great you entered a number between 1 and 5"
;;
*)echo "Wrong number..bye"
break
;;
esac
done
[root@test zwc]# ./breakout
Enter any namber [1..5] :3
great you entered a number between 1 and 5
Enter any namber [1..5] :8
Wrong number..bye
[root@test zwc]#
(跳出循环,回到shell提示符下)
18.8.3 continue
continue命令不会跳出循环,只是跳过这个循环
18.8.4 浏览文件行
[root@test zwc]# cat name2.txt
------LISTING OF PERSONNAL FILE----
--- TAKEN AS AT 06/1999 ----
Louise Conrad:Accounts:ACC8987
Peter James:Payroll:RP489
Fred Terms:Customer:CUS012
James Lenod:Accounts:ACC887
Frank Pavely:Payroll:RP487
[root@test zwc]# cat whilecontinue
#!/bin/sh
#whilecontinue
SAVEDIFS=$IFS
IFS=:
INPUT_FILE=name2.txt
NAME_HOLD="Peter James"
LINE_NO=0
if [ -s $INPUT_FILE ]; then
while read NAME DEPT ID
do
LINE_NO=`expr $LINE_NO + 1`
if [ "$LINE_NO" -le "2" ]; then
#skip if the count is less than 2
continue
fi
if [ "$NAME" = "$NAME_HOLD" ]; then
#skip if the name in NAME_HOLD is Peter James
continue
else
echo "$NAME $DEPT $ID"
#all the processing goes here
fi
done < $INPUT_FILE
IFS=$SAVEDIFS
else
echo "`basename $0` : Sorry file not found or there is no date in the file"
exit1
fi
[root@test zwc]#chmod 750 whilecontinue
[root@test zwc]# ./whilecontinue
Louise Conrad Accounts ACC8987
Fred Terms Customer CUS012
James Lenod Accounts ACC887
Frank Pavely Payroll RP487
18.9菜单
[root@test zwc]# cat menu
#!/bin/sh
# menu
# set the date, user and hostname up
MYDATE=`date +%d/%m/%y`
THIS_HOST=`hostname -s`
USER=`whoami`
#loop forever!
while :
do
# clear the screen
tput clear
# here documents starts here
cat <<MAYDAY
--------------------------------------------------------------------
User: $USER Host:$THIS_HOST Date:$MYDATE
--------------------------------------------------------------------
1 : List files in current directory
2 : Use the vi editor
3 : See who is on the system
H : Help screen
Q : Exit Menu
----------------------------------------------------------------------
MAYDAY
# here document finished
echo -e -n "\tYour Choice [1,2,3,H,Q] >"
read CHOICE
case $CHOICE in
1)ls
;;
2)vi
;;
3)who
;;
H|h)
# use a here document for the help screen
cat <<MAYDAY
This is the help screen,nothing here yet to help you!
MAYDAY
;;
Q|q)exit 0
;;
*)echo -e "\t\007unknown user response "
;;
esac
echo -e -n "\tHit the return key to continue"
read DUMMY
done
[root@test zwc]#chmod 750 menu
[root@test zwc]#./menu
--------------------------------------------------------------------
User: root Host:test Date:25/09/08
--------------------------------------------------------------------
1 : List files in current directory
2 : Use the vi editor
3 : See who is on the system
H : Help screen
Q : Exit Menu
----------------------------------------------------------------------
Your Choice [1,2,3,H,Q] >3
root :0 Sep 24 20:15
root pts/1 Sep 25 00:32 (:0.0)
root pts/2 Sep 25 03:20 (:0.0)
Hit the return key to continue