原文地址:http://vbird.dic.ksu.edu.tw/linux_basic/0340bashshell-scripts_5.php

回圈 (loop)

除了 if...then...fi 这种条件判断式之外,回圈可能是程序当中最重要的一环了~ 回圈可以不断的运行某个程序段落,直到使用者配置的条件达成为止。 所以,重点是那个『条件的达成』是什么。除了这种依据判断式达成与否的不定回圈之外, 还有另外一种已经固定要跑多少次的回圈形态,可称为固定回圈的形态呢!底下我们就来谈一谈:


while do done, until do done (不定回圈)

一般来说,不定回圈最常见的就是底下这两种状态了:

while [ condition ]  <==中括号内的状态就是判断式
do <==do 是回圈的开始!
程序段落
done <==done 是回圈的结束

while 的中文是『当....时』,所以,这种方式说的是『当 condition 条件成立时,就进行回圈,直到 condition 的条件不成立才停止』的意思。还有另外一种不定回圈的方式:

until [ condition ]
do
程序段落
done

这种方式恰恰与 while 相反,它说的是『当 condition 条件成立时,就终止回圈, 否则就持续进行回圈的程序段。』是否刚好相反啊~我们以 while 来做个简单的练习好了。 假设我要让使用者输入 yes 或者是 YES 才结束程序的运行,否则就一直进行告知使用者输入字串。

[root@www scripts]# vi sh13.sh
#!/bin/bash
# Program:
# Repeat question until user input correct answer.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH while [ "$yn" != "yes" -a "$yn" != "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."

上面这个例题的说明是『当 $yn 这个变量不是 "yes" 且 $yn 也不是 "YES" 时,才进行回圈内的程序。』 而如果 $yn 是 "yes" 或 "YES" 时,就会离开回圈罗~那如果使用 until 呢?呵呵有趣罗~ 他的条件会变成这样:

[root@www scripts]# vi sh13-2.sh
#!/bin/bash
# Program:
# Repeat question until user input correct answer.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH until [ "$yn" == "yes" -o "$yn" == "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."

仔细比对一下这两个东西有啥不同喔! ^_^再来,如果我想要计算 1+2+3+....+100 这个数据呢? 利用回圈啊~他是这样的:

[root@www scripts]# vi sh14.sh
#!/bin/bash
# Program:
# Use loop to calculate "1+2+3+...+100" result.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH s=0 # 这是加总的数值变量
i=0 # 这是累计的数值,亦即是 1, 2, 3....
while [ "$i" != "100" ]
do
i=$(($i+1)) # 每次 i 都会添加 1
s=$(($s+$i)) # 每次都会加总一次!
done
echo "The result of '1+2+3+...+100' is ==> $s"

嘿嘿!当你运行了『 sh sh14.sh 』之后,就可以得到 5050 这个数据才对啊!这样了呼~ 那么让你自行做一下,如果想要让使用者自行输入一个数字,让程序由 1+2+... 直到你输入的数字为止, 该如何撰写呢?应该很简单吧?答案可以参考一下习题练习里面的一题喔!


for...do...done
(固定回圈)

相对於 while, until 的回圈方式是必须要『符合某个条件』的状态, for 这种语法,则是『 已经知道要进行几次回圈』的状态!他的语法是:

for var in con1 con2 con3 ...
do
程序段
done

以上面的例子来说,这个 $var 的变量内容在回圈工作时:

  1. 第一次回圈时, $var 的内容为 con1 ;
  2. 第二次回圈时, $var 的内容为 con2 ;
  3. 第三次回圈时, $var 的内容为 con3 ;
  4. ....

我们可以做个简单的练习。假设我有三种动物,分别是 dog, cat, elephant 三种, 我想每一行都输出这样:『There are dogs...』之类的字样,则可以:

[root@www scripts]# vi sh15.sh
#!/bin/bash
# Program:
# Using for .... loop to print 3 animals
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH for animal in dog cat elephant
do
echo "There are ${animal}s.... "
done

等你运行之后就能够发现这个程序运行的情况啦!让我们想像另外一种状况,由於系统上面的各种帐号都是写在 /etc/passwd 内的第一个栏位,你能不能透过管线命令的 cut 捉出单纯的帐号名称后,以 id 及 finger 分别检查使用者的识别码与特殊参数呢?由於不同的
Linux 系统上面的帐号都不一样!此时实际去捉 /etc/passwd 并使用回圈处理,就是一个可行的方案了!程序可以如下:

[root@www scripts]# vi sh16.sh
#!/bin/bash
# Program
# Use id, finger command to check system account's information.
# History
# 2009/02/18 VBird first release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
users=$(cut -d ':' -f1 /etc/passwd) # 撷取帐号名称
for username in $users # 开始回圈进行!
do
id $username
finger $username
done

运行上面的脚本后,你的系统帐号就会被捉出来检查啦!这个动作还可以用在每个帐号的删除、重整上面呢! 换个角度来看,如果我现在需要一连串的数字来进行回圈呢?举例来说,我想要利用 ping 这个可以判断网络状态的命令, 来进行网络状态的实际侦测时,我想要侦测的网域是本机所在的 192.168.1.1~192.168.1.100,由於有 100 台主机, 总不会要我在 for 后面输入 1 到 100 吧?此时你可以这样做喔!

[root@www scripts]# vi sh17.sh
#!/bin/bash
# Program
# Use ping command to check the network's PC state.
# History
# 2009/02/18 VBird first release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
network="192.168.1" # 先定义一个网域的前面部分!
for sitenu in $(seq 1 100) # seq 为 sequence(连续) 的缩写之意
do
# 底下的程序在取得 ping 的回传值是正确的还是失败的!
ping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1
# 开始显示结果是正确的启动 (UP) 还是错误的没有连通 (DOWN)
if [ "$result" == 0 ]; then
echo "Server ${network}.${sitenu} is UP."
else
echo "Server ${network}.${sitenu} is DOWN."
fi
done

上面这一串命令运行之后就可以显示出 192.168.1.1~192.168.1.100 共 100 部主机目前是否能与你的机器连通! 如果你的网域与鸟哥所在的位置不同,则直接修改上头那个 network 的变量内容即可!其实这个范例的重点在 $(seq ..) 那个位置!那个 seq 是连续 (sequence) 的缩写之意!代表后面接的两个数值是一直连续的! 如此一来,就能够轻松的将连续数字带入程序中罗!

最后,让我们来玩判断式加上回圈的功能!我想要让使用者输入某个目录档名, 然后我找出某目录内的档名的权限,该如何是好?呵呵!可以这样做啦~

[root@www scripts]# vi sh18.sh
#!/bin/bash
# Program:
# User input dir name, I find the permission of files.
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH # 1. 先看看这个目录是否存在啊?
read -p "Please input a directory: " dir
if [ "$dir" == "" -o ! -d "$dir" ]; then
echo "The $dir is NOT exist in your system."
exit 1
fi # 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 回圈的功能吧!主要用在数值方面的处理喔!


for...do...done
的数值处理

除了上述的方法之外,for 回圈还有另外一种写法!语法如下:

for (( 初始值; 限制值; 运行步阶 ))
do
程序段
done

这种语法适合於数值方式的运算当中,在 for 后面的括号内的三串内容意义为:

  • 初始值:某个变量在回圈当中的起始值,直接以类似 i=1 配置好;
  • 限制值:当变量的值在这个限制值的范围内,就继续进行回圈。例如 i<=100;
  • 运行步阶:每作一次回圈时,变量的变化量。例如 i=i+1。

值得注意的是,在『运行步阶』的配置上,如果每次添加 1 ,则可以使用类似『i++』的方式,亦即是 i 每次回圈都会添加一的意思。好,我们以这种方式来进行 1 累加到使用者输入的回圈吧!

[root@www scripts]# vi sh19.sh
#!/bin/bash
# Program:
# Try do calculate 1+2+....+${your_input}
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH read -p "Please input a number, I will count for 1+2+...+your_input: " nu s=0
for (( i=1; i<=$nu; i=i+1 ))
do
s=$(($s+$i))
done
echo "The result of '1+2+3+...+$nu' is ==> $s"

Linux学习之二十、循环的更多相关文章

  1. Linux学习之二十-Linux文件系统

    Linux文件系统 文件系统的定义 文件系统是操作系统的必备软件,文件系统是对一个存储设备上的数据(block)和元数据(inode)进行组织的一种机制.文件系统可以帮助用户管理磁盘空间,进行文件的快 ...

  2. Linux学习(二十)软件安装与卸载(三)源码包安装

    一.概述 源码包安装的优点在于它自由程度比较高,可以指定目录与组件.再有,你要是能改源码也可以. 二.安装方法 步骤 1.从官网或者信任站点下载源码包 [root@localhost ~]# wget ...

  3. Linux学习总结(十二)—— CentOS用户管理:创建用户、修改用户、修改密码、密码有效期、禁用账户、解锁账户、删除用户、查看所有用户信息

    文章首发于Linux学习总结(十二)-- CentOS用户管理,请尊重原创保留原文链接. 创建用户 useradd -g webadmin -d /home/zhangsan zhangsan pas ...

  4. 学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环

    目录 学习笔记:CentOS7学习之二十二: 结构化命令case和for.while循环 22.1 流程控制语句:case 22.2 循环语句 22.1.2 for-do-done 22.3 whil ...

  5. 学习笔记:CentOS7学习之二十五:shell中色彩处理和awk使用技巧

    目录 学习笔记:CentOS7学习之二十五:shell中色彩处理和awk使用技巧 25.1 Shell中的色彩处理 25.2 awk基本应用 25.2.1 概念 25.2.2实例演示 25.3 awk ...

  6. 学习笔记:CentOS7学习之二十四:expect-正则表达式-sed-cut的使用

    目录 学习笔记:CentOS7学习之二十四:expect-正则表达式-sed-cut的使用 24.1 expect实现无交互登录 24.1.1 安装和使用expect 24.2 正则表达式的使用 24 ...

  7. 学习笔记:CentOS7学习之二十:shell脚本的基础

    目录 学习笔记:CentOS7学习之二十:shell脚本的基础 20.1 shell 基本语法 20.1.1 什么是shell? 20.1.2 编程语言分类 20.1.3 什么是shell脚本 20. ...

  8. Linux学习总结(十四)—— 查看CPU信息

    文章首发于[博客园-陈树义],点击跳转到原文Linux学习总结(十四)-- 查看CPU信息. Linux学习总结(十四)-- 查看CPU信息 商用服务器CPU最常用的是 Intel Xeon 系列,该 ...

  9. python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码

    python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...

随机推荐

  1. SQL Server 的 6 种隔离级别

    背景知识: 高并发一直以来是数据的所追求的目标,然,一般事物是有两面性的.不多说了,等下变邪教了.下面直接看 并发性最高的隔离级别 read uncommitted 1. read uncommitt ...

  2. 一步一步学python(四) - 字典

    1.字典的使用 创建字典:phonebook = {'Alice': '1234' , 'Beth':'9120'} 2.dict函数 >>>items = [('name','Gu ...

  3. select自动选中

    //筛选 var typeid = "<!--{$typeid}-->"; var bigclassid = "<!--{$bigclassid}--& ...

  4. Unix/Linux环境C编程入门教程(26) 字符数字那些事儿

    1.gcvt() strtod() strtol() strtoul() toascii() tolower() toupper函数介绍 gcvt(将浮点型数转换为字符串,取四舍五入) 相关函数 ec ...

  5. hdu 1150 Machine Schedule hdu 1151 Air Raid 匈牙利模版

    //两道大水……哦不 两道结论题 结论:二部图的最小覆盖数=二部图的最大匹配数 有向图的最小覆盖数=节点数-二部图的最大匹配数 //hdu 1150 #include<cstdio> #i ...

  6. SpringNote01.基于SpringMVC-Hibernate的Blog系统

    最近,在学习Spring,做这样一个简单的blog系统,主要是让自己动手练习使用Spring,熟练的使用才干进一步的深入学习.该项目使用Maven构建,使用git进行代码管理,通过这样一个小项目,熟悉 ...

  7. Hadoop--初识Hadoop

    什么是Hadoop? 搞什么东西之前,第一步是要知道What(是什么),然后是Why(为什么),最后才是How(怎么做).但很多开发的朋友在做了多年项目以后,都习惯是先How,然后What,最后才是W ...

  8. SNMP协议具体解释

    简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议.在1988年被制定,并被Internet体系结构委员会(IAB)採纳作为一个短期的网络管理解决方式:因为SNMP的简单性,在Inter ...

  9. 单调旋转数组的TopK问题

    问题描述:输入一个单调旋转后的数组,求该数组中的第k小的元素. 分析:很多人看到这个题目会有点懵,可能读者不知道什么是旋转数组,我先解释下两个概念, 旋转数组的定义:把一个数组的前几项元素移动到数组的 ...

  10. css系列教程--overflow min/maxheight content

    outline:这只轮廓样式,与border类似.写法参考border. overflow/overflow-x/overflow-y:visible/hidden/scroll/auto/no-di ...