Shell控制流程结构
- 本章内容有:
退出状态
While、for和until loops循环
If then else语句
脚本中动作
菜单 - 条件控制语句
If then else语句
if语句测试条件,测试条件返回真(0)或假(1)后,可相应执行一系列语句。if语句结
构对错误检查非常有用。其格式为:
then 命令1
elif 条件2
then 命令2
else 命令3
fi
让我们来具体讲解if语句的各部分功能。
Then 那么
命令1 执行命令1
elif 条件2 如果条件1不成立
then 那么
命令2 执行命令2
else 如果条件1,2均不成立
命令3 那么执行命令3
fi 完成
if语句必须以单词fi终止。在if语句中漏写fi是最一般的错误。我自己有时也是这样。elif和else为可选项,如果语句中没有否则部分,那么就不需要elif和else部分。If语句可以有许多elif部分。最常用的if语句是if then fi结构。例题1:
#!/bin/sh
#author: li0924
if [ -lt ];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 >&
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语句格式如下:
模式1)
命令1
. . .
;;
模式2)
命令2
. . .
;;
esac
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
)
echo "you select 1"
;;
)
echo "you select 2"
;;
)
echo "you select 3"
;;
)
echo "you select 4"
;;
)
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
;;
esac
- 循环控制语句
for循环控制语句
for循环一般格式为:
do
command
command
...
done
当变量值在列表里,for循环即执行一次所有命令,使用变量名访问列表中取值。命令可为任何有效的shell命令和语句。变量名为任何单词。In列表用法是可选的,如果不用它,for循环使用命令行的位置参数。
in列表可以包含替换、字符串和文件名,下面看一些例子
例题一:此例仅显示列表1 2 3 4 5,用变量名访问列表:
#!/bin/sh
#author: li0924
for i in
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
else
exit
fi
done
for循环嵌入
嵌入循环可以将一个for循环嵌在另一个for循环内
do
for varname2 in list2
do
command
. . .
done
done
while循环
while循环用于不断执行一系列命令,也用于从输入文件中读取数据,其格式为:
do
command
command
...
done
虽然通常只使用一个命令,但在while和do之间可以放几个命令。命令通常用作测试条件。只有当命令的退出状态为0时,do和done之间命令才被执行,如果退出状态不是0,则循
环终止。命令执行完毕,控制返回循环顶部,从头开始直至测试条件为假
题目一:以下是一个基本的while循环,测试条件是:如果COUNTER小于5,那么条件返回真。COUNTER从0开始,每次循环处理时, COUNTER加1
#!/bin/sh
#author: li0924
counter=
while [ $counter -lt ]
do
echo "$counter"
counter=`expr $counter + `
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来代替!
总结:以上代码都很简单;容易理解学习!都经过测试!