Shell控制流程结构
- 本章内容有:
退出状态
While、for和until loops循环
If then else语句
脚本中动作
菜单
条件控制语句
If then else语句
if语句测试条件,测试条件返回真(0)或假(1)后,可相应执行一系列语句。if语句结
构对错误检查非常有用。其格式为:
if 条件1
then 命令1
elif 条件2
then 命令2
else 命令3
fi
View Code
让我们来具体讲解if语句的各部分功能。
1 If 条件1 如果条件1为真
2 Then 那么
3 命令1 执行命令1
4 elif 条件2 如果条件1不成立
5 then 那么
6 命令2 执行命令2
7
else 如果条件1,2均不成立
8 命令3 那么执行命令3
9 fi 完成
View Code
if语句必须以单词fi终止。在if语句中漏写fi是最一般的错误。我自己有时也是这样。elif和else为可选项,如果语句中没有否则部分,那么就不需要elif和else部分。If语句可以有许多elif部分。最常用的if语句是if then fi结构。例题1:
#!/bin/sh
#author: li0924
if [
10 -lt
12 ];then
echo
"
Yes, you are right
"
fi
注意;then不要跟if一行;若是一行则需要添加;
例题二:通过测试设置为接受用户输入的变量可以测知用户是否输入信息。下面的例子中测试用户键入return键后变量name是否包含任何信息
#!/bin/sh
#author: li0924
echo -n
"
ENTRY YOUR NAME:
"
read name
#
"
$name
" =
"" or -n $name
if [ -n $name ];then
echo
"
please input you name!
"
fi
例题三:不必拘泥于变量或数值测试,也可以测知系统命令是否成功返回。对grep使用if语句找出grep是否成功返回信息
#!/bin/sh
#author: li0924
if grep -i
"
ready
" * > /dev/
null
2>&
1
then
echo
"
it is ready;here
"
fi
例题四:环境变量用于测试条件,即LOGNAME是否包含root值。这类语句是加在脚本开头作为一安全性准则的普遍方法。当然LOGNAME可用于测试任何有效用
#!/bin/sh
#author: li0924
if [ $LOGNAME =
"
root
" ];then
echo
"
the LOGNAME is root
"
else
echo
"
NO
"
fi
#!/bin/sh
#author: li0924
echo -n
"
please input your login name:
"
read name
if [ -z $name ];then
echo
"
please input your login name:
"
elif [
"
$name
" =
"
root
" ];then
echo
"
hello root
";
elif [
"
$name
" =
"
li0924
" ];then
echo
"
hello li0924
";
elif [
"
$name
" =
"
lottu
" ];then
echo
"
hello lottu
";
fi
case语句
case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
case语句格式如下:
case 值in
模式1)
命令1
. . .
;;
模式2)
命令2
. . .
;;
esac
View Code
case工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至;;。取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号*捕获该值,再接受其他输入。
例题1:提示输入1到5,输入数字传入case语句,变量ANS设置为case取值测试变量ANS,ANS将与每一模式进行比较。如果匹配成功,则执行模式里面的命令直至;;,这里只反馈非用户数字选择的信息,然后case退出,因为匹配已找到
#!/bin/sh
#author: li0924
echo -n
"
please input 1-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
"
$0 :this is not between 1 and 5
"
;;
esac
例题二:使用case时,也可以指定“|”符号作为或命令,例如vt100|vt102匹配模式vt100或vt102。下面的例子中,要求用户输入终端类型。如果输入为vt100或vt102,将匹配模式‘vt100|vt102’,执行命令是设置TERM变量为vt100。如果用户输入与模式不匹配,*用来捕获输入,其中命令为将TERM设置为vt100。最后在case语句外,导出TERM变量
#!/bin/sh
echo
"
choose vt100,vt102,vt200
"
echo -n
"
please select one:
"
read TERM
case $TERM
in
vt100|vt102)
TERM=vt100
;;
vt200)
TERM=vt200
;;
*)
TERM=
"
VT
"
;;
esac
echo
"
$TERM
"
例题三:case的一个有效用法是提示用户响应以决定是否继续进程。这里提示输入y以继续处理,n退出。如果用户输入Y,y或yes,处理继续执行case语句后面部分。如果用户输入N,n或no或其他响应,用户退出脚本
#!/bin/sh
#author: li094
echo
"
Do you wish next
"
read I
case $I
in
Y|y|yes)
echo
"
OK
"
;;
N|n|no)
echo
"
NO
"
;;
*)
echo
"
unkown select
"
exit
1
;;
esac
for循环控制语句
for循环一般格式为:
for varname
in list
do
command
1
command
2
...
done
View Code
当变量值在列表里,for循环即执行一次所有命令,使用变量名访问列表中取值。命令可为任何有效的shell命令和语句。变量名为任何单词。In列表用法是可选的,如果不用它,for循环使用命令行的位置参数。
in列表可以包含替换、字符串和文件名,下面看一些例子
例题一:此例仅显示列表1 2 3 4 5,用变量名访问列表:
#!/bin/sh
#author: li0924
for i
in
1
2
3
4
5
do
echo $i
done
例题二:对for循环使用ls命令;这个循环执行ls命令,打印当前目录下所有文件
#!/bin/sh
#author: li0924
for i
in `ls`
do
echo $i
done
例题三:In列表用法是可选的,如果不用它,for循环使用命令行的位置参数
#!/bin/sh
#author: li0924
for i
do
echo
"
this is $i paramter
"
done
例题四:用for循环备份所有文件,只需将变量作为cp命令的目标参数。这里有一变量.bak,当在循环中使用cp命令时,它作为此命令目标文件名。列表命令为ls。只针对普通文件;非文件夹
#!/bin/sh
#author: li0924
for i
in `ls -l | awk
'
{if(substr($1,1,1)=="-") print $NF}
'`
do
if cp $i $i.bak
then
exit
0
else
exit
1
fi
done
for循环嵌入
嵌入循环可以将一个for循环嵌在另一个for循环内
for varname1
in list1
do
for varname2
in list2
do
command
1
. . .
done
done
View Code
while循环
while循环用于不断执行一系列命令,也用于从输入文件中读取数据,其格式为:
while command
do
command
1
command
2
...
done
View Code
虽然通常只使用一个命令,但在while和do之间可以放几个命令。命令通常用作测试条件。只有当命令的退出状态为0时,do和done之间命令才被执行,如果退出状态不是0,则循
环终止。命令执行完毕,控制返回循环顶部,从头开始直至测试条件为假
题目一:以下是一个基本的while循环,测试条件是:如果COUNTER小于5,那么条件返回真。COUNTER从0开始,每次循环处理时, COUNTER加1
#!/bin/sh
#author: li0924
counter=
0
while [ $counter -lt
5 ]
do
echo
"
$counter
"
counter=`expr $counter +
1`
done
题目二:while循环最常用于从一个文件中读取数据,因此编写脚本可以处理这样的信息。假定要从下面包含雇员名字、从属部门及其ID号的一个文件中读取信息文件worker.txt
Louise Conrad:Accounts:ACC8987
Peter Jamas:Payroll:PR489
Fred Terms:Customer:CUS012
James Lenod:Accounts:ACC887
Frank Pavely:Payroll:PR489
#!/bin/sh
#author: li0924
while read list
do
echo $list;
done < worker.txt
例题三:输出时要去除冒号域分隔符,可使用变量IFS。在改变它之前保存IFS的当前设置。然后在脚本执行完后恢复此设置。使用IFS可以将域分隔符改为冒号而不是空格或tab键
#!/bin/sh
#author: li0924
#SAVEIFS=$IFS
IFS=:
while read name dept id
do
echo -e
"
$name\t$dept\t$id
"
done < worker.txt
#IFS=$SAVEIFS
注意:只要理解上面脚本的意思就行了;完全可以用awk来代替!
总结:以上代码都很简单;容易理解学习!都经过测试!