打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Bourne Shell及shell编程 3

(5)循环控制
 <1> while循环:
 格式
 while command
 do
 command
 command
 command
 ...
 done
 
 例 计算1到5的平方
 #!/bin/sh
 #
 #Filename: square.sh
 int=1
 
 while [ $int -le 5 ]
 do
 sq=`expr $int \* $int`
 echo $sq
 int=`expr $int + 1`
 done
 echo "Job completed"
 
 $ sh square.sh
 1
 4
 9
 16
 25

 Job completed
 
 <2> until循环结构
 格式
 until command
 do
 command
 command
 ....
 command
 done
 
 示例使用until结构计算1-5的平方
 #!/bin/sh
 
 int=1
 
 until [ $int -gt 5 ]
 do
 sq=`expr $int \* $int`
 echo $sq
 int=`expr $int + 1`
 done
 echo "Job completed"
 
 <3> 使用shift对不定长的参数进行处理
 在以上的示例中我们总是假设命令行参数唯一或其个数固定或者
使用$*将整个命
 行参数传递给shell script进行处理对于参数个数不固定并且希
望对每个命令参
 进行单独处理时则需要shift命令使用shift可以将命令行位置参
数依次移动位置
 
 即$2->$1, $3->$2. 在移位之前的第一个位置参数$1在移位后将
不在存在
 
 示例如下
 
 #!/bin/sh
 #
 #Filename: shifter
 

 until [ $# -eq 0 ]
 do
 echo "Argument is $1 and `expr $# - 1` argument(s) remain"
 shift
 done
 
 
 $ shifter 1 2 3 4
 Argument is 1 and 3 argument(s) remain
 Argument is 2 and 2 argument(s) remain
 Argument is 3 and 1 argument(s) remain
 Argument is 4 and 0 argument(s) remain
 $
 
 使用shift时每进行一次移位$#减1使用这一特性可以用until循环对每个参
 数进行处理如下示例中是一个求整数和的shell script:
 
 #!/bin/sh
 # sumints - a program to sum a series of integers
 #
 
 if [ $# -eq 0 ]
 then
 echo "Usage: sumints integer list"
 exit 1
 fi
 
 sum=0
 
 until [ $# -eq 0 ]
 do
 sum=`expr $sum + $1`
 shift
 done
 echo $sum
 
 
 $ sh sumints 324 34 34 12 34
 438
 $
 

 使用shift的另一个原因是Bourne Shell的位置参数变量为$1~$9,
因此通过位置变
 只能访问前9个参数但这并不等于在命令行上最多只能输入9
个参数此时如果想
访问
 前9个参数之后的参数就必须使用shift.
 
 另外shift后可加整数进行一次多个移位如
 
 shift 3
 
 
 <4>. for循环
 格式
 for var in arg1 arg2 ... argn
 do
 command
 ....
 command
 done
 
 示例
 $ for letter in a b c d e; do echo $letter;done
 a
 b
 c
 d
 e
 
 对当前目录下的所有文件操作
 $ for i in *
 do
 if [ -f $i ]
 then
 echo "$i is a file"
 elif [ -d $i ]
 echo "$i is a directory"
 fi
 done
 
 求命令行上所有整数之和
 #!/bin/sh
 

 sum=0
 
 for INT in $*
 do
 sum=`expr $sum + $INT`
 done
 
 echo $sum
 
 
 <6> 从循环中退出 break和continue命令
 break 立即退出循环
 continue 忽略本循环中的其他命令继续下一下循环
 
 在shell编程中有时我们要用到进行无限循环的技巧也就是说这
种循环一直执行
 到break或continue命令这种无限循环通常是使用true或false
命令开始的UNIX
 系统中的true总是返加0值而false则返回非零值如下所示

 
 #一直执行到程序执行了break或用户强行中断时才结束循环
 while true
 do
 command
 ....
 command
 done
 
 上面所示的循环也可以使用until false, 如下
 
 until false
 do
 command
 ....
 command
 done
 
 在如下shell script中同时使用了continue,break以及case语句中
的正规表达式用
 
 #!/bin/sh

 # Interactive program to restore, backup, or unload
 # a directory
 
 echo "Welcome to the menu driven Archive program"
 
 while true
 do
 # Display a Menu
 echo
 echo "Make a Choice from the Menu below"
 echo _
 echo "1 Restore Archive"
 echo "2 Backup directory"
 echo "3 Unload directory"
 echo "4 Quit"
 echo
 
 # Read the user's selection
 echo -n "Enter Choice: "
 
 read CHOICE
 
 case $CHOICE in
 [1-3] ) echo
 # Read and validate the name of the directory
 
 echo -n "What directory do you want? "
 read WORKDIR
 
 if [ ! -d "$WORKDIR" ]
 then
 echo "Sorry, $WORKDIR is not a directory"
 continue
 fi
 
 # Make the directory the current working directory
 cd $WORKDIR;;
 
 4) :;; # :为空语句不执行任何动作
 *) echo "Sorry, $CHOICE is not a valid choice"


 continue
 esac
 
 case "$CHOICE" in
 1) echo "Restoring..."
 cpio -i </dev/rmt/0h;;
 
 2) echo "Archiving..."
 ls | cpio -o >/dev/rmt/0h;;
 
 3) echo "Unloading..."
 ls | cpio -o >/dev/rmt/0h;;
 
 4) echo "Quitting"
 break;;
 esac
 
 #Check for cpio errors
 
 if [ $? -ne 0 ]
 then
 echo "A problem has occurred during the process"
 if [ $CHOICE = 3 ]
 then
 echo "The directory will not be erased"
 fi
 
 echo "Please check the device and try again"
 continue
 else
 if [ $CHOICE = 3 ]
 then
 rm *
 fi
 fi
 done
 
(6)结构化编程定义函数
 同其他高级语言一样shell也提供了函数功能函数通常也称之为子过
程(subroutine)
,
 其定义格式如下
 

 funcname()
 {
 command
 ...
 command; #分号
 }
 
 定义函数之后可以在shell中对此函数进行调用使用函数定义可以将
一个复杂的程序
 为多个可管理的程序段如下所示
 
 # start program
 
 setup ()
 { command list ; }
 
 do_data ()
 { command list ; }
 
 cleanup ()
 { command list ; }
 
 errors ()
 { command list ; }
 
 setup
 do_data
 cleanup
 # end program
 
 技巧
 . 在对函数命名时最好能使用有含义的名字即函数名能够比较准
确的描述函数所
完成
 的任务
 . 为了程序的维护方便请尽可能使用注释
 
 
 使用函数的另一个好处就是可以在一个程序中的不同地方执行相同的
命令序列(函数),
 如下所示
 
 iscontinue()

 {
 while true
 do
 echo -n "Continue?(Y/N)"
 read ANSWER
 
 case $ANSWER in
 [Yy]) return 0;;
 [Nn]) return 1;;
 *) echo "Answer Y or N";;
 esac
 done
 }
 
 这样可以在shell编程中调用iscontinue确定是否继续执行
 
 if iscontinue
 then
 continue
 else
 break
 fi
 
 
 ** shell函数与shell程序非常相似但二者有一个非常重要的差别shell程序是由子sh
ell
 执行的而shell函数则是作为当前shell的一部分被执行的因此在
当前shell中可以
 变函数的定义此外在任意shell(包括交互式的shell)中均可定义函数
 
 $ dir
 dir: not found
 $ dir () { ls -l ;}
 $ dir
 total 5875
 -rw-r--r-- 1 hbwork 100 Nov 10 23:16 doc
 -rw-r--r-- 1 hbwork 2973806 Nov 10 23:47 ns40docs.zip
 -rw-r--r-- 1 hbwork 1715011 Nov 10 23:30 ns840usr.pdf
 -rw-r--r-- 1 hbwork 1273409 Sep 23 1998 radsol21b6.tar.
Z
 -rw-r--r-- 1 hbwork 7526 Nov 10 23:47 wget-log

 -rw-r--r-- 1 hbwork 1748 Nov 13 21:51 wget-log.1
 $ unset dir
 $ dir () {
 > echo "Permission Link Owner Group File_SZ LastAccess
FileName"
 > echo "-----------------------------------------------------------"
 > ls -l $*;
 > }
 
 $ dir
 Permission Link Owner Group File_SZ LastAccess FileName
 -----------------------------------------------------------
 total 5875
 -rw-r--r-- 1 hbwork 100 Nov 10 23:16 doc
 -rw-r--r-- 1 hbwork 2973806 Nov 10 23:47 ns40docs.zip

 -rw-r--r-- 1 hbwork 1715011 Nov 10 23:30 ns840usr.pdf

 -rw-r--r-- 1 hbwork 1273409 Sep 23 1998 radsol21b6.tar.Z
 -rw-r--r-- 1 hbwork 7526 Nov 10 23:47 wget-log
 -rw-r--r-- 1 hbwork 1748 Nov 13 21:51 wget-log.1
 
 通常情况下shell script是在子shell中执行的困此在此子shell中
对变量所作的
 修改对父shell不起作用点(.) 命令使用shell在不创建子shell而由
当前shell读取
 并执行一个shell script, 可以通过这种方式来定义函数及变量此外
点(.)命令最
 常用的功能就是通过读取.profile来重新配置初始化login变量如下
所示
 
 $ . .profile
 (csh相对于.命令的是source命令).
 
(7)使用And/Or结构进行有条件的命令执行
 <1> And , 仅当第一个命令成功时才有执行后一个命令,如同在逻辑与表
达式中如果前面的
 结果为真时才有必要继续运算否则结果肯定为假
 
 格式如下
 
 command1 && command2

 
 例rm $TEMPDIR/* && echo "File successfully removed"
 
 等价于
 
 if rm $TEMPDIR/*
 then
 echo "File successfully removed"
 fi
 
 <2>Or, 与AND相反仅当前一个命令执行出错时才执行后一条命令
 
 例 rm $TEMPDIR/* || echo "File not removed"
 
 等价与
 
 if rm $TEMPDIR/*
 then
 command
 else
 echo "File not removed"
 fi
 
 <3> 混合命令条件执行
 command1 && command2 && command3
 当command1, command2成功时才执行command3
 
 command1 && command2 || comamnd3
 仅当command1成功command2失败时才执行command3
 
 当然可以根据自己的需要进行多种条件命令的组合在此不多讲述
 
 
(8) 使用getopts命令读取unix格式选项
 UNIX格式选项指如下格式的命令行参数
 command -options parameters
 
 使用格式
 getopts option_string variable
 
 具体使用方法请参考getopts的在线文档(man getopts).
 
 示例如下
 

 #newdate
 if [ $# -lt 1 ]
 then
 date
 else
 while getopts mdyDHMSTjJwahr OPTION
 do
 case $OPTION
 in
 m) date '+%m ';; # Month of Year
 d) date '+%d ';; # Day of Month
 y) date '+%y ';; # Year
 D) date '+%D ';; # MM/DD/YY
 H) date '+%H ';; # Hour
 M) date '+%M ';; # Minute
 S) date '+%S ';; # Second
 T) date '+%T ';; # HH:MM:SS
 j) date '+%j ';; # day of year
 J) date '+%y%j ';;# 5 digit Julian date
 w) date '+%w ';; # Day of the Week
 a) date '+%a ';; # Day abbreviation
 h) date '+%h ';; # Month abbreviation
 r) date '+%r ';; # AM-PM time
 \?) echo "Invalid option $OPTION";;
 esac
 done
 fi
 
 $ newdate -J
 94031
 $ newdate -a -h -d
 Mon
 Jan
 31
 $ newdate -ahd
 Mon
 Jan
 31
 $
 
 
 示例程序复制程序
 
 # Syntax: duplicate [-c integer] [-v] filename

 # where integer is the number of duplicate copies
 # and -v is the verbose option
 
 COPIES=1
 VERBOSE=N
 
 
 while getopts vc: OPTION
 do
 case $OPTION
 in
 c) COPIES=$OPTARG;;
 v) VERBOSE=Y;;
 \?) echo "Illegal Option"
 exit 1;;
 esac
 done
 
 if [ $OPTIND -gt $# ]
 then
 echo "No file name specified"
 exit 2
 fi
 
 
 shift `expr $OPTIND -1`
 
 FILE=$1
 COPY=0
 
 while [ $COPIES -gt $COPY ]
 do
 COPY=`expr $COPY + 1`
 cp $FILE ${FILE}${COPY}
 if [ VERBOSE = Y ]
 then
 echo ${FILE}${COPY}
 fi
 done
 
 
 $ duplicate -v fileA
 fileA1
 $ duplicate -c 3 -v fileB

 fileB1
 fileB2
 fileB3

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
shell 十三問之第三问:別人 echo、你也 echo ,是問 echo 知多少
echo命令行
SHELL十三问之三:别人 echo、你也 echo ,是问 echo 知多少
shell之用command在终端判断是否存在这个命令
shell程序编写从入门到精通(下)
shell调试技术
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服