while [ condition ] <==中括号内的状态就是判断式do<==do是循环的开始!程序段落done<==done 是循环的结束
while 的中文是“当....时”,所以,这种方式说的是“当 condition 条件成立时,就进行循环,直到 condition 的条件不成立才停止”的意思。还有另外一种不定循环的方式:
until [ condition ]do程序段落done
这种方式恰恰与 while 相反,它说的是“当 condition 条件成立时,就终止循环, 否则就持续进行循环的程序段。”是否刚好相反啊~我们以 while 来做个简单的练习好了。 假设我要让使用者输入 yes 或者是 YES 才结束程序的执行,否则就一直进行告知使用者输入字串。
[dmtsai@study bin]$ vim yes_to_stop.sh#!/bin/bash# Program:# Repeat question until user input correct answer.# History:# 2015/07/17 VBird First releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHwhile [ "${yn}"!="yes"-a"${yn}"!="YES" ]doread-p"Please input yes/YES to stop this program: "yndoneecho"OK! you input the correct answer."
[dmtsai@study bin]$ vim yes_to_stop-2.sh#!/bin/bash# Program:# Repeat question until user input correct answer.# History:# 2015/07/17 VBird First releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHuntil [ "${yn}"=="yes"-o"${yn}"=="YES" ]doread-p"Please input yes/YES to stop this program: "yndoneecho"OK! you input the correct answer."
[dmtsai@study bin]$ vim cal_1_100.sh#!/bin/bash# Program:# Use loop to calculate "1+2+3+...+100" result.# History:# 2015/07/17 VBird First releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHs=0# 这是加总的数值变量i=0# 这是累计的数值,亦即是 1, 2, 3....while [ "${i}"!="100" ]do i=$(($i+1))# 每次 i 都会增加 1 s=$(($s+$i))# 每次都会加总一次!doneecho"The result of '1+2+3+...+100' is ==> $s"
嘿嘿!当你执行了“ sh cal_1_100.sh ”之后,就可以得到 5050 这个数据才对啊!这样瞭呼~ 那么让你自行做一下,如果想要让使用者自行输入一个数字,让程序由 1+2+... 直到你输入的数字为止, 该如何撰写呢?应该很简单吧?答案可以参考一下[习题练习]里面的一题喔!
12.5.2 for...do...done (固定循环)
相对于 while, until 的循环方式是必须要“符合某个条件”的状态, for 这种语法,则是“ 已经知道要进行几次循环”的状态!他的语法是:
for var incon1con2con3...do程序段done
以上面的例子来说,这个 $var 的变量内容在循环工作时:
第一次循环时, $var 的内容为 con1 ;
第二次循环时, $var 的内容为 con2 ;
第三次循环时, $var 的内容为 con3 ;
....
我们可以做个简单的练习。假设我有三种动物,分别是 dog, cat, elephant 三种, 我想每一行都输出这样:“There are dogs...”之类的字样,则可以:
[dmtsai@study bin]$ vim show_animal.sh#!/bin/bash# Program:# Using for .... loop to print 3 animals# History:# 2015/07/17 VBird First releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHfor animal indogcatelephantdoecho"There are ${animal}s.... "done
[dmtsai@study bin]$ vim userid.sh#!/bin/bash# Program# Use id, finger command to check system account's information.# History# 2015/07/17 VBird first releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHusers=$(cut-d':'-f1/etc/passwd)# 撷取帐号名称for username in ${users} # 开始循环进行!doid ${username}done
[dmtsai@study bin]$ vim dir_perm.sh#!/bin/bash# Program:# User input dir name, I find the permission of files.# History:# 2015/07/17 VBird First releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATH# 1\. 先看看这个目录是否存在啊?read-p"Please input a directory: "dirif [ "${dir}"==""-o!-d"${dir}" ]; thenecho"The ${dir} is NOT exist in your system."exit1fi# 2\. 开始测试文件啰~filelist=$(ls ${dir})# 列出所有在该目录下的文件名称for filename in ${filelist}do perm=""test-r"${dir}/${filename}"&& perm="${perm} readable"test-w"${dir}/${filename}"&& perm="${perm} writable"test-x"${dir}/${filename}"&& perm="${perm} executable"echo"The file ${dir}/${filename}'s permission is ${perm} "done
呵呵!很有趣的例子吧~利用这种方式,你可以很轻易的来处理一些文件的特性呢。接下来,让我们来玩玩另一种 for 循环的功能吧!主要用在数值方面的处理喔!
12.5.3 for...do...done 的数值处理
除了上述的方法之外,for 循环还有另外一种写法!语法如下:
for (( 初始值; 限制值; 执行步阶))do程序段done
这种语法适合于数值方式的运算当中,在 for 后面的括号内的三串内容意义为:
初始值:某个变量在循环当中的起始值,直接以类似 i=1 设置好;
限制值:当变量的值在这个限制值的范围内,就继续进行循环。例如 i<=100;
执行步阶:每作一次循环时,变量的变化量。例如 i=i+1。
值得注意的是,在“执行步阶”的设置上,如果每次增加 1 ,则可以使用类似“i++”的方式,亦即是 i 每次循环都会增加一的意思。好,我们以这种方式来进行 1 累加到使用者输入的循环吧!
[dmtsai@study bin]$ vim cal_1_100-2.sh#!/bin/bash# Program:# Try do calculate 1+2+....+${your_input}# History:# 2015/07/17 VBird First releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHread-p"Please input a number, I will count for 1+2+...+your_input: "nus=0for (( i=1; i<=${nu}; i=i+1))do s=$((${s}+${i}))doneecho"The result of '1+2+3+...+${nu}' is ==> ${s}"
[dmtsai@study bin]$ vim what_to_eat.sh#!/bin/bash# Program:# Try do tell you what you may eat.# History:# 2015/07/17 VBird First releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHeat[1]="卖当当漢堡包"# 写下你所收集到的店家!eat[2]="肯爷爷炸鸡"eat[3]="彩虹日式便当"eat[4]="越油越好吃大雅"eat[5]="想不出吃啥学餐"eat[6]="太师父便当"eat[7]="池上便当"eat[8]="怀念火车便当"eat[9]="一起吃方便面"eatnum=9# 需要输入有几个可用的餐厅数!check=$(( ${RANDOM} * ${eatnum} /32767+1))echo"your may eat ${eat[${check}]}"
[dmtsai@study bin]$ vim what_to_eat-2.sh#!/bin/bash# Program:# Try do tell you what you may eat.# History:# 2015/07/17 VBird First releasePATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexport PATHeat[1]="卖当当漢堡包"eat[2]="肯爷爷炸鸡"eat[3]="彩虹日式便当"eat[4]="越油越好吃大雅"eat[5]="想不出吃啥学餐"eat[6]="太师父便当"eat[7]="池上便当"eat[8]="怀念火车便当"eat[9]="一起吃方便面"eatnum=9eated=0while [ "${eated}"-lt3 ]; do check=$(( ${RANDOM} * ${eatnum} /32767+1)) mycheck=0if [ "${eated}"-ge1 ]; thenfor i in $(seq1 ${eated} )doif [ ${eatedcon[$i]} == $check ]; then mycheck=1fidonefiif [ ${mycheck} ==0 ]; thenecho"your may eat ${eat[${check}]}" eated=$(( ${eated} +1))eatedcon[${eated}]=${check}fidone