返回顶部
首页 > 资讯 > 精选 >怎么用Bash编程实现循环
  • 490
分享到

怎么用Bash编程实现循环

2023-06-16 03:06:44 490人浏览 八月长安
摘要

这篇文章主要介绍怎么用Bash编程实现循环,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!循环我使用过的所有编程语言都至少有两种循环结构来用来执行重复的操作。我经常使用 for 循环,然而我发现 while 和 unt

这篇文章主要介绍怎么用Bash编程实现循环,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

循环

我使用过的所有编程语言都至少有两种循环结构来用来执行重复的操作。我经常使用 for 循环,然而我发现 whileuntil 循环也很有用处。

for 循环

我的理解是,在 bash 中实现的 for 命令比大部分语言灵活,因为它可以处理非数字的值;与之形成对比的是,诸如标准 C 语言的 for 循环只能处理数字类型的值。

Bash 版的 for 命令基本的结构很简单:

for Var in list1 ; do list2 ; done

解释一下:“对于 list1 中的每一个值,把 $Var 设置为那个值,使用该值执行 list2 中的程序语句;list1 中的值都执行完后,整个循环结束,退出循环。” list1 中的值可以是一个简单的显式字符串值,也可以是一个命令执行后的结果(`` 包含其内的命令执行的结果,本系列第二篇文章中有描述)。我经常使用这种结构。

测试它,确认 ~/testdir 仍然是当前的工作目录(PWD)。删除目录下所有东西,来看下这个显式写出值列表的 for 循环的简单的示例。这个列表混合了字母和数字 — 但是不要忘了,在 bash 中所有的变量都是字符串或者可以被当成字符串来处理。

[student@studentvm1 testdir]$ rm *[student@studentvm1 testdir]$ for I in a b c d 1 2 3 4 ; do echo $I ; doneabcd1234

给变量赋予更有意义的名字,变成前面版本的进阶版:

[student@studentvm1 testdir]$ for Dept in "Human Resources" Sales Finance "InfORMation Technology" Engineering Administration Research ; do echo "Department $Dept" ; doneDepartment Human ResourcesDepartment SalesDepartment FinanceDepartment Information TechnologyDepartment EngineeringDepartment AdministrationDepartment Research

创建几个目录(创建时显示一些处理信息):

[student@studentvm1 testdir]$ for Dept in "Human Resources" Sales Finance "Information Technology" Engineering Administration Research ; do echo "Working on Department $Dept" ; mkdir "$Dept"  ; doneWorking on Department Human ResourcesWorking on Department SalesWorking on Department FinanceWorking on Department Information TechnologyWorking on Department EngineeringWorking on Department AdministrationWorking on Department Research[student@studentvm1 testdir]$ lltotal 28drwxrwxr-x 2 student student 4096 Apr  8 15:45  Administrationdrwxrwxr-x 2 student student 4096 Apr  8 15:45  Engineeringdrwxrwxr-x 2 student student 4096 Apr  8 15:45  Financedrwxrwxr-x 2 student student 4096 Apr  8 15:45 'Human Resources'drwxrwxr-x 2 student student 4096 Apr  8 15:45 'Information Technology'drwxrwxr-x 2 student student 4096 Apr  8 15:45  Researchdrwxrwxr-x 2 student student 4096 Apr  8 15:45  Sales

mkdir 语句中 $Dept 变量必须用引号包裹起来;否则名字中间有空格(如 Information Technology)会被当做两个独立的目录处理。我一直信奉的一条实践规则:所有的文件和目录都应该为一个单词(中间没有空格)。虽然大部分现代的操作系统可以处理名字中间有空格的情况,但是系统管理员需要花费额外的精力去确保脚本和  CLI 程序能正确处理这些特例。(即使它们很烦人,也务必考虑它们,因为你永远不知道将拥有哪些文件。)

再次删除 ~/testdir 下的所有东西 — 再运行一次下面的命令:

[student@studentvm1 testdir]$ rm -rf * ; lltotal 0[student@studentvm1 testdir]$ for Dept in Human-Resources Sales Finance Information-Technology Engineering Administration Research ; do echo "Working on Department $Dept" ; mkdir "$Dept"  ; doneWorking on Department Human-ResourcesWorking on Department SalesWorking on Department FinanceWorking on Department Information-TechnologyWorking on Department EngineeringWorking on Department AdministrationWorking on Department Research[student@studentvm1 testdir]$ lltotal 28drwxrwxr-x 2 student student 4096 Apr  8 15:52 Administrationdrwxrwxr-x 2 student student 4096 Apr  8 15:52 Engineeringdrwxrwxr-x 2 student student 4096 Apr  8 15:52 Financedrwxrwxr-x 2 student student 4096 Apr  8 15:52 Human-Resourcesdrwxrwxr-x 2 student student 4096 Apr  8 15:52 Information-Technologydrwxrwxr-x 2 student student 4096 Apr  8 15:52 Researchdrwxrwxr-x 2 student student 4096 Apr  8 15:52 Sales

假设现在有个需求,需要列出一台 linux 机器上所有的 RPM  包并对每个包附上简短的描述。我为北卡罗来纳州工作的时候,曾经遇到过这种需求。由于当时开源尚未得到州政府的“批准”,而且我只在台式机上使用  Linux,对技术一窍不通的老板(PHB)需要我列出我计算机上安装的所有软件,以便他们可以“批准”一个特例。

你怎么实现它?有一种方法是,已知 rpm –qa 命令提供了 RPM 包的完整描述,包括了白痴老板想要的东西:软件名称和概要描述。

让我们一步步执行出最后的结果。首先,列出所有的 RPM 包:

[student@studentvm1 testdir]$ rpm -qaperl-Http-Message-6.18-3.fc29.noarchperl-IO-1.39-427.fc29.x86_64perl-Math-Complex-1.59-429.fc29.noarchlua-5.3.5-2.fc29.x86_64java-11-openjdk-headless-11.0.ea.28-2.fc29.x86_64util-linux-2.32.1-1.fc29.x86_64libreport-fedora-2.9.7-1.fc29.x86_64rpcbind-1.2.5-0.fc29.x86_64libsss_sudo-2.0.0-5.fc29.x86_64libfontenc-1.1.3-9.fc29.x86_64<snip>

sortuniq 命令对列表进行排序和打印去重后的结果(有些已安装的 RPM 包具有相同的名字):

[student@studentvm1 testdir]$ rpm -qa | sort | uniqa2ps-4.14-39.fc29.x86_64aajohan-comfortaa-fonts-3.001-3.fc29.noarchabattis-cantarell-fonts-0.111-1.fc29.noarchabiWord-3.0.2-13.fc29.x86_64abrt-2.11.0-1.fc29.x86_64abrt-addon-ccpp-2.11.0-1.fc29.x86_64abrt-addon-coredump-helper-2.11.0-1.fc29.x86_64abrt-addon-kerneloops-2.11.0-1.fc29.x86_64abrt-addon-pstoreoops-2.11.0-1.fc29.x86_64abrt-addon-vmcore-2.11.0-1.fc29.x86_64<snip>

以上命令得到了想要的 RPM 列表,因此你可以把这个列表作为一个循环的输入信息,循环最终会打印每个 RPM 包的详细信息:

[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done

这段代码产出了多余的信息。当循环结束后,下一步就是提取出白痴老板需要的信息。因此,添加一个 egrep 命令用来搜索匹配 ^Name^Summary 的行。脱字符(^)表示行首,整个命令表示显示所有以 Name 或 Summary 开头的行。

[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done | egrep -i "^Name|^Summary"Name        : a2psSummary     : Converts text and other types of files to PostScriptName        : aajohan-comfortaa-fontsSummary     : Modern style true type fontName        : abattis-cantarell-fontsSummary     : Humanist sans serif fontName        : abiwordSummary     : Word processing programName        : abrtSummary     : Automatic bug detection and reporting tool<snip>

在上面的命令中你可以试试用 grep 代替 egrep ,你会发现用 grep 不能得到正确的结果。你也可以通过管道把命令结果用 less 过滤器来查看。最终命令像这样:

[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done | egrep -i "^Name|^Summary" > RPM-summary.txt

这个命令行程序用到了管道、重定向和 for 循环,这些全都在一行中。它把你的 CLI 程序的结果重定向到了一个文件,这个文件可以在邮件中使用或在其他地方作为输入使用。

这个一次一步构建程序的过程让你能看到每步的结果,以此来确保整个程序以你期望的流程进行且输出你想要的结果。

白痴老板最终收到了超过 1900 个不同的 RPM 包的清单,我严重怀疑根本就没人读过这个列表。我给了他们想要的东西,没有从他们嘴里听到过任何关于 RPM 包的信息。

其他循环

Bash 中还有两种其他类型的循环结构:whileuntil 结构,两者在语法和功能上都类似。这些循环结构的基础语法很简单:

while [ expression ] ; do list ; done

逻辑解释:表达式(expression)结果为 true 时,执行程序语句 list。表达式结果为 false 时,退出循环。

until [ expression ] ; do list ; done

逻辑解释:执行程序语句 list,直到表达式的结果为 true。当表达式结果为 true 时,退出循环。

While 循环

while 循环用于当逻辑表达式结果为 true 时执行一系列程序语句。假设你的 PWD 仍是 ~/testdir

最简单的 while 循环形式是这个会一直运行下去的循环。下面格式的条件语句永远以 true 作为返回。你也可以用简单的 1 代替 true,结果一样,但是这解释了 true 表达式的用法。

[student@studentvm1 testdir]$ X=0 ; while [ true ] ; do echo $X ; X=$((X+1)) ; done | head0123456789[student@studentvm1 testdir]$

既然你已经学了 CLI 的各部分知识,那就让它变得更有用处。首先,为了防止变量 $X 在前面的程序或 CLI 命令执行后有遗留的值,设置 $X 的值为 0。然后,因为逻辑表达式 [ true ] 的结果永远是 1,即 true,在 dodone 中间的程序指令列表会一直执行 — 或者直到你按下 Ctrl+C 抑或发送一个 2 号信号给程序。那些程序指令是算数扩展,用来打印变量 $X 当前的值并加 1.

《系统管理员的 Linux 哲学》的信条之一是追求优雅,实现优雅的一种方式就是简化。你可以用操作符 ++ 来简化这个程序。在第一个例子中,变量当前的值被打印出来,然后变量的值增加了。可以在变量后加一个 ++ 来表示这个逻辑:

[student@studentvm1 ~]$ X=0 ; while [ true ] ; do echo $((X++)) ; done | head0123456789

现在删掉程序最后的 | head 再运行一次。

在下面这个版本中,变量在值被打印之前就自增了。这是通过在变量之前添加 ++ 操作符实现的。你能看出区别吗?

[student@studentvm1 ~]$ X=0 ; while [ true ] ; do echo $((++X)) ; done | head123456789

你已经把打印变量的值和自增简化到了一条语句。类似 ++ 操作符,也有 -- 操作符。

你需要一个在循环到某个特定数字时终止循环的方法。把 true 表达式换成一个数字比较表达式来实现它。这里有一个循环到 5 终止的程序。在下面的示例代码中,你可以看到 -le 是 “小于或等于” 的数字逻辑操作符。整个语句的意思:只要 $X 的值小于或等于 5,循环就一直运行。当 $X 增加到 6 时,循环终止。

[student@studentvm1 ~]$ X=0 ; while [ $X -le 5 ] ; do echo $((X++)) ; done012345[student@studentvm1 ~]$
Until 循环

until 命令非常像 while 命令。不同之处是,它直到逻辑表达式的值是 true 之前,会一直循环。看一下这种结构最简单的格式:

[student@studentvm1 ~]$ X=0 ; until false  ; do echo $((X++)) ; done | head0123456789[student@studentvm1 ~]$

它用一个逻辑比较表达式来计数到一个特定的值:

[student@studentvm1 ~]$ X=0 ; until [ $X -eq 5 ]  ; do echo $((X++)) ; done01234[student@studentvm1 ~]$ X=0 ; until [ $X -eq 5 ]  ; do echo $((++X)) ; done12345[student@studentvm1 ~]$

以上是“怎么用Bash编程实现循环”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

--结束END--

本文标题: 怎么用Bash编程实现循环

本文链接: https://lsjlt.com/news/282312.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么用Bash编程实现循环
    这篇文章主要介绍怎么用Bash编程实现循环,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!循环我使用过的所有编程语言都至少有两种循环结构来用来执行重复的操作。我经常使用 for 循环,然而我发现 while 和 unt...
    99+
    2023-06-16
  • bash编程中循环语句怎么用
    这篇文章将为大家详细讲解有关bash编程中循环语句怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。if 是单分支语句,使用格式如下: if condition ; then statement ….....
    99+
    2023-06-09
  • 怎么在Bash中编写循环
    本篇文章给大家分享的是有关怎么在Bash中编写循环,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。使用for循环和find命令自动对多个文件执行一组操作。人们想要学习Unix s...
    99+
    2023-06-28
  • bash 编程中循环语句用法
    1.if 是单分支语句,使用格式如下: if condition ; then statement ….. fi 2.if … else 是双分支语句,使用格式如下: if condition ; then...
    99+
    2022-06-04
    语句 bash
  • 怎么在Linux的bash中实现永远循环
    这篇文章主要介绍了怎么在Linux的bash中实现永远循环,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在 Linux 中有很多永远循环(或直到你决定停止)的方法,你可以在命...
    99+
    2023-06-15
  • 怎么在Bash中使用循环
    这篇文章将为大家详细讲解有关怎么在Bash中使用循环,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。人们希望学习批处理命令的一个普遍原因是要得到批处理强大的功能。如果你希望批量的对文件执行一些指令,构造一个...
    99+
    2023-06-16
  • JavaScript循环作用域怎么实现
    这篇文章主要讲解了“JavaScript循环作用域怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript循环作用域怎么实现”吧!   ...
    99+
    2024-04-02
  • NodeJS中怎么实现循环引用
    这篇文章将为大家详细讲解有关NodeJS中怎么实现循环引用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。场景复现出现问题场景比较简单,一共四个类:paren...
    99+
    2024-04-02
  • mysql怎么实现for循环
    MySQL不支持像其他编程语言中的for循环那样直接在查询中使用。但是可以借助存储过程或事件来实现类似的功能。下面分别介绍两种方法:...
    99+
    2024-04-09
    mysql
  • 如何在Linux中shell编程实现for循环
    今天就跟大家聊聊有关如何在Linux中shell编程实现for循环,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、常用for循环结构#语法一for 变量 in&...
    99+
    2023-06-09
  • shell脚本编程之循环语句怎么用
    小编给大家分享一下shell脚本编程之循环语句怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在运行脚本时重复执行一系列的命令是很常见的,这时我们就需要使用循...
    99+
    2023-06-09
  • 怎么在VBS中实现循环
    本篇文章为大家展示了怎么在VBS中实现循环,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。For...Next:指定循环次数,使用计数器重复运行语句Do...Loop:当条件为 true 或者直到条件...
    99+
    2023-06-08
  • C#怎么实现无限循环
    本篇内容主要讲解“C#怎么实现无限循环”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#怎么实现无限循环”吧!循环控制语句循环控制语句更改执行的正常序列。当执行离开一个范围时,所有在该范围中创建...
    99+
    2023-06-17
  • PHP中怎么实现foreach循环
    这期内容当中小编将会给大家带来有关PHP中怎么实现foreach循环,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。< html> < body>&nb...
    99+
    2023-06-17
  • Python中怎么实现for循环
    这篇文章将为大家详细讲解有关Python中怎么实现for循环,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。For循环如何在Python中工作Python的for循环通过遍历数组的序列来工作。...
    99+
    2023-06-15
  • Scala无限循环怎么实现
    本篇内容主要讲解“Scala无限循环怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala无限循环怎么实现”吧!有的时候,我们可能需要多次执行同一块代码。一般情况下,语句是按顺序执行的...
    99+
    2023-06-19
  • JAVA怎么实现循环队列
    在Java中,可以使用数组和指针来实现循环队列。以下是一个简单的循环队列的实现示例:```javapublic class Circ...
    99+
    2023-09-23
    JAVA
  • Node.js事件循环怎么实现
    这篇文章主要介绍“Node.js事件循环怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Node.js事件循环怎么实现”文章能帮助大家解决问题。在进程启动时,Node 便会创建一个类似于&nb...
    99+
    2023-07-04
  • python怎样实现循环
    这篇文章主要介绍了python怎样实现循环,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。range函数的使用作为循环遍历的对象第一种创建方式r=range(10)print(...
    99+
    2023-06-22
  • 怎么在Shell中实现程序造死循环
    本篇文章为大家展示了怎么在Shell中实现程序造死循环,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。实现方法可是怎么在shell脚本中写死循环呢?这个时候同样用到while,归纳汇总了让Shell脚...
    99+
    2023-06-09
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作