保持你的循环——Bash For、While、Until 循环示例

举报
Tiamo_T 发表于 2022/03/07 21:37:30 2022/03/07
【摘要】 循环语句用于强制程序重复执行语句,执行的语句称为循环体。 循环一直执行,直到控制表达式的值为 0。控制表达式可以是任何标量数据类型。

循环语句用于强制程序重复执行语句,执行的语句称为循环体。

循环一直执行,直到控制表达式的值为 0。控制表达式可以是任何标量数据类型。

shell 语言还提供了几个迭代或循环语句。在本文中,让我们通过一些示例来了解 bash 提供的循环语句。

Bash 支持以下三种循环语句

  1. for循环
  2. While 循环
  3. Until

循环可以嵌套。与任何其他编程语言一样,bash 也支持 break 语句退出当前循环,并支持 continue 语句恢复循环语句的下一次迭代。

Bash For 循环 – 第一种方法

当在进入 bash 循环之前知道迭代次数时,通常使用 for 循环。Bash 支持两种 for 循环。bash for 循环的第一种形式是:

for varname in list
	do
		commands ##Body of the loop
	done

在上面的语法中:

  • for、in、do 和 done 是关键字
  • 列表是具有项目列表的任何列表
  • varname 是任何 Bash 变量名。

在这种形式中,for 语句执行包含在正文中的命令,对列表中的每个项目执行一次。每次循环时,列表​​中的当前项目都将存储在变量“varname”中。这个 varname 可以在循环体中处理。此列表可以是一个变量,其中包含由空格分隔的多个单词。如果 for 语句中缺少 list,则它采用传递给 shell 的位置参数。

Bash For Loop 示例 1. 解压所有 Zip 文件

以下示例在根目录中查找与“*.zip*”匹配的文件列表,并在该 zip 文件所在的相同位置创建一个新目录,并解压缩该 zip 文件内容。

# cat zip_unzip.sh
#! /bin/bash
# Find files which has .zip
for file in `find /root -name "*.zip*" -type f`
do

# Skip the extension .zip
dirname=`echo ${file} | awk -F'.' '{print $1}'`

# Create the directory
mkdir $dirname

# Copy the zip file
cp ${file} ${dirname}
cd $dirname

# Unzip the zip file from newly created directory
unzip ${dirname}/$(echo ${file##/*/})
done
  • 在此示例中,find 命令返回文件列表,其中每个文件都将通过循环进行处理。
  • 对于每个项目,它都会使用 zip 文件的名称创建目录,并将 zip 文件复制到新创建的目录并从那里解压缩 zip 文件。
  • echo 语句 echo ${file##/*/} 只给你文件名而不是路径。
# ./zip_unzip.sh
Archive:  /root/test2/test2.zip
 extracting: t1/p
 extracting: t1/q
 extracting: t1/r
 extracting: t1/s
 extracting: t1/t
 extracting: t1/u
 extracting: t1/v
Archive:  /root/test1/test1.zip
 extracting: t/a
 extracting: t/b
 extracting: t/c
 extracting: t/d
 extracting: t/e

与 Bash 循环类似,Awk 还提供了我们在Awk While 和 For 循环文章中讨论的 for 循环和 while 循环。

Bash For 循环 – 第二种方法

for循环的第二种形式类似于'C'编程语言中的for循环,它具有三个表达式(初始化、条件和更新)。

for (( expr1; expr2; expr3 ))
         do
		commands
         done
  • 在上面的 bash for 命令语法中,在第一次迭代之前, expr1 被评估。这通常用于初始化循环的变量。
  • do 和 done 之间的所有语句都会重复执行,直到 expr2 的值为 TRUE。
  • 在循环的每次迭代之后,都会评估 expr3。这通常用于增加循环计数器。

以下示例生成 n 个随机数。

Bash 示例 2. 生成 n 个随机数

$ cat random.sh
#! /bin/bash

echo -e "How many random numbers you want to generate"
read max

for (( start = 1; start <= $max; start++ ))
do
        echo -e $RANDOM
done

$ ./random.sh
How many random numbers you want to generate
5
6119
27200
1998
12097
9181

在上面的代码片段中,for 循环以最大次数生成随机数。RANDOM 是一个内部 bash 函数,它在每次调用时返回一个随机整数。

Bash While 循环

Shell 编程语言提供的另一个迭代语句是 while 语句。

Syntax:
while expression
do
	commands
done

在上面的while循环语法中:

  • while、do、done 是关键字
  • 表达式是返回标量值的任何表达式
  • While 语句导致在提供的条件表达式为真时执行代码块。

Bash While 示例 3. 将内容写入文件

以下示例从标准输出读取数据并写入文件。

$ cat writefile.sh
#! /bin/bash

echo -e "Enter absolute path of the file name you want to create"
read file
while read line
do
echo $line >> $file
done

$ sh writefile.sh
Enter absolute path of the file name you want to create
/tmp/a
while
for
until

$ cat /tmp/a
while
for
until

上面的例子,从用户那里读取文件名,并从标准输入读取数据行并将每一行附加到给定的文件名。当EOF进入时,读取会失败,所以循环到此结束。

如果您正在编写大量 bash 脚本,您可以使用 Vim 编辑器作为 Bash IDE,使用我们之前讨论的Vim bash-support 插件

Bash While 示例 4. 读取文件的内容

在前面的示例中,它从 stdout 读取数据并将其写入文件。在此示例中,它读取文件
内容并将其写入标准输出。

$ cat read.sh
#! /bin/bash
echo -e "Enter absolute path of the file name you want to read"
read file
exec <$file # redirects stdin to a file
while read line
do
echo $line
done

$ ./read.sh

Enter absolute path of the file name you want to read
/tmp/a
while
for
until

在此示例中,它获取要读取的文件名,并使用 exec 将标准输入重定向到文件。从那时起,所有标准输入都来自该文件,而不是来自键盘。read 命令从标准输入读取行,所以 while 循环读取标准输入,直到 EOF 发生。

until循环

until 语句在语法和功能上与 while 语句非常相似。两者之间唯一真正的区别是,当条件表达式为假时,直到语句执行其代码块,而当条件表达式为真时,while 语句执行其代码块。

syntax:

until expression
	do
	   commands #body of the loop
	done

在上面的 bash until 语法中:
where until, do, done 是关键字
表达式 任何条件表达式

Bash until Example 5. 监控日志文件

此示例监视日志文件的大小,一旦日志文件大小达到 2000 字节,它将获取该日志文件的副本。

$ cat monitor.sh

file=/tmp/logfile
until [ $(ls -l $file | awk '{print $5}') -gt 2000 ]
        do
            echo "Sleeping for next 5 seconds"
            sleep 5
        done
date=`date +%s`
cp $file "$file-"$date.bak

$ ./monitor.sh
Sleeping for next 5 seconds
Sleeping for next 5 seconds

$ ls -l /tmp/logfile*
-rw-r--r-- 1 sss sss      2010 Jun 24 12:29 logfile
-rw-r--r-- 1 sss sss      2005 Jun 24 16:09 logfile-1277474574.bak

until 语句继续执行循环体,直到条件变为真。在此示例中,条件是文件大小大于 2000 字节,因此一旦文件达到 2000 字节,它就会复制该文件。

Bash until Example 6. 等待机器启动

此示例用于等待机器启动,然后再对该机器执行 ssh。直到循环语句仅在 ping 给出响应时结束。

$ cat mac_wait.sh
#! /bin/bash

read -p "Enter IP Address:" ipadd
echo $ipadd
until ping -c 1 $ipadd
do
        sleep 60;
done
ssh $ipadd

$./mac_wait.sh
Enter IP Address:192.143.2.10
PING 192.143.2.10 (192.143.2.10) 56(84) bytes of data.

--- 192.143.2.10 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

PING 192.143.2.10 (192.143.2.10) 56(84) bytes of data.
64 bytes from 192.143.2.10: icmp_seq=1 ttl=64 time=0.059 ms

--- 192.143.2.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.059/0.059/0.059/0.000 ms
The authenticity of host '192.143.2.10 (192.143.2.10)' can't be established.
Are you sure you want to continue connecting (yes/no)? yes

until循环在命令行中非常有用,作为等待某些事件发生的一种方式。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。