本节介绍linux shell流程控制的相关知识。
[ -f "somefile" ] :判断是否是一个文件
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限 [ -n "$var" ] :判断$var变量是否有值 [ "$a" = "$b" ] :判断$a和$b是否相等
执行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进行了比较。
快捷操作符
复制代码代码示例:
[ -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" 一行。如果不可读则或操作生效,打印错误信息后脚本退出。这里有个问题,那就是我们必须有两个命令:
2.case
复制代码代码示例:
case ... in
...) do something here ;; esac
例子,file命令可以辨别出一个给定文件的文件类型,比如:
复制代码代码示例:
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. selsect
复制代码代码示例:
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"
运行结果:
4.loop
以下例子中,将分别打印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
这里出现了第二个特殊的变量$*,该变量包含了所有输入的命令行参数值。
5. 引号
复制代码代码示例:
#!/bin/sh
echo "*.jpg" echo '*.jpg'
这将打印"*.jpg" 两次。
复制代码代码示例:
#!/bin/sh
echo $SHELL echo "$SHELL" echo '$SHELL'
运行结果:
复制代码代码示例:
echo \*.jpg
echo \$SHELL
这将输出:
6. Here documents
复制代码代码示例:
#!/bin/sh
# we have less than 3 arguments. Print the help text: if [ $# -lt 3 ] ; then cat < ren -- renames a number of files using sed regular expressions USAGE: ren 'regexp' 'replacement' files... EXAMPLE: rename all *.HTM files in *.html: ren 'HTM$' 'html' *.HTM HELP exit 0 fi OLD="$1" NEW="$2" # The shift command removes one argument from the list of # command line arguments. shift shift # $* contains now all the files: for file in $*; do if [ -f "$file" ] ; then newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"` if [ -f "$newfile" ]; then echo "ERROR: $newfile exists already" else echo "renaming $file to $newfile ..." mv "$file" "$newfile" fi fi done 这是一个复杂一些的例子。
第一个if表达式判断输入命令行参数是否小于3个(特殊变量$#表示包含参数的个数)。 下一步,我们使用shift命令将第一个和第二个参数从参数列表中删除,这样原来的第三个参数就成为参数列表$*的第一个参数。然后我们开始循环,命令行参数列表被一个接一个地被赋值给变量$file。接着我们判断该文件是否存在,如果存在则通过sed命令搜索和替换来产生新的文件名。
然后,将反短斜线内命令结果赋值给newfile。这样就达到了目的:得到了旧文件名和新文件名。 |