shell教程四:流程控制语句

时间:2022-09-08 16:42:53

流程控制语句 

3.1、if 


"if" 表达式 如果条件为真则执行then后面的部分: 

if ....; then 

.... 
elif ....; then 
.... 
else 
.... 
fi

大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件
是否存在及是否可读等等… 
通常用" [ ] "来表示条件测试。注意这里的空格很重要。要确保方括号的空格。 
[ -f "somefile" ] :判断是否是一个文件 
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限 
[ -n "$var" ] :判断$var变量是否有值 
[ "$a" = "$b" ] :判断$a和$b是否相等 ,注意“=”和变量之间要有空格。
[ -r "$mailfolder" ] :该脚本首先判断mailfolder是否可读
执行man test可以查看所有测试表达式可以比较和判断的类型。 

直接执行以下脚本: 
#!/bin/sh 
if [ "$SHELL" = "/bin/bash" ]; then 
echo "your login shell is the bash (bourne again shell)" 
else 
echo "your login shell is not bash but $SHELL" 
fi 

变量$SHELL包含了登录shell的名称,我们和/bin/bash进行了比较。


3.2、快捷操作符&&和||

熟悉C语言的朋友可能会很喜欢下面的表达式: 
[ -f "/etc/shadow" ] && echo "This computer uses shadow passwors" 
这里 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句。

您也可以认为是逻辑运算中的与操作。上例中表示如果/etc/shadow文件存在
则打印” This computer uses shadow passwors”。

同样或操作(||)在shell编程中也是可用的。
这里有个例子: 
#!/bin/sh 
mailfolder=/var/spool/mail/james 
[ -r "$mailfolder" ]||{ echo "Can not read $mailfolder" ; exit 1; } 
echo "$mailfolder has mail from:" 
grep "^From " $mailfolder

该脚本首先判断mailfolder是否可读。如果可读则打印该文件中的"From" 一行。如果不可读
则或操作生效,打印错误信息后脚本退出。这里有个问题,那就是我们必须有两个命令: 
-打印错误信息 
-退出程序 
我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用。一般函数将在下文提及。 

不用与和或操作符,我们也可以用if表达式作任何事情,但是使用与或操作符会更便利很多。


3.3、case

case :表达式可以用来匹配一个给定的字符串,而不是数字。 
case ... in 
...) do something here ;; 
esac 
以下是一个使用case的实例:
dirs=`ls $sourceRoot/android | tr '\n' ' '`
for i in $dirs
do
sourceFold=$sourceRoot/android/${i}
case ${i} in 
out)
echo "skip ${i}";;

kernel|frameworks|vendor|build)
cp -rfu $sourceFold $workRoot/android
echo "copy ${i}";;

*) 
ln -sf $sourceFold $workRoot/android
echo "linking ${i}";;
esac
done
再让我们看一个例子。 file命令可以辨别出一个给定文件的文件类型,比如: 
file lf.gz 
这将返回: 
lf.gz: gzip compressed data, deflated, original filename, 
last modified: Mon Aug 27 23:09:18 2001, os: Unix 
下面有个一个叫做smartzip的脚本,该脚本可以自动解压bzip2, gzip 和zip 类型的压缩文件: 

#!/bin/sh 
ftype=`file "$1"` 
case "$ftype" in 
"$1: Zip archive"*) 
unzip "$1" ;; 
"$1: gzip compressed"*) 
gunzip "$1" ;; 
"$1: bzip2 compressed"*) 
bunzip2 "$1" ;; 
*) echo "File $1 can not be uncompressed with smartzip";; 
esac 
您可能注意到我们在这里使用了一个特殊的变量$1。该变量包含了传递给该程序的第一个参数值。
也就是说,当我们运行: 
smartzip articles.zip 
$1 就是字符串 articles.zip


3.4、 selsect

select 表达式是一种bash的扩展应用,尤其擅长于交互式使用。用户可以从一组不同的值中进行选择。 
select var in ... ; do 
break 
done 
.... now $var can be used .... 
下面是一个例子: 
#!/bin/sh 
echo "What is your favourite OS?" 


select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do 
break 
done 


echo "You have selected $var" 
下面是该脚本运行的结果: 
What is your favourite OS? 
1) Linux 
2) Gnu Hurd 
3) Free BSD 
4) Other 
#? 1 
You have selected Linux
注意:select是扩展应用。

3.4、while

while表达式: 
while ...; do 
.... 
done 
当while中的表达式为真时,将一直循环。
可以用关键字"break" 用来跳出循环;也可以用关键字”continue”用来不执行余下的部分而直接跳到下一个循环。
实例3-4-1
#!/bin/sh 
num=10
while [ ! "$num" = "0" ]; do 
#num=num-1
num=`expr "$num" "-" "1"` 
echo $num
done

3.5、for

for-loop表达式查看一个字符串列表 (字符串用空格分隔) 然后将其赋给一个变量: 
for var in ....; do 
.... 
done 
在下面的例子中,将分别打印ABC到屏幕上: 
#!/bin/sh 
for var in A B C ; do 
echo "var is $var" 
done 


下面是一个更为有用的脚本showrpm,其功能是打印一些RPM包的统计信息: 
#!/bin/sh 
# list a content summary of a number of RPM packages 
# USAGE: showrpm rpmfile1 rpmfile2 ... 
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm 
for rpmpackage in $*; do 
if [ -r "$rpmpackage" ];then 
echo "=============== $rpmpackage ==============" 
rpm -qi -p $rpmpackage 
else 
echo "ERROR: cannot read file $rpmpackage" 
fi 
done 
这里出现了第二个特殊的变量$*,该变量包含了所有输入的命令行参数值。
如果您运行showrpm openssh.rpm w3m.rpm webgrep.rpm 
此时 $* 包含了 3 个字符串,即openssh.rpm, w3m.rpm and webgrep.rpm.