保持你的循环——Bash For、While、Until 循环示例
循环语句用于强制程序重复执行语句,执行的语句称为循环体。
循环一直执行,直到控制表达式的值为 0。控制表达式可以是任何标量数据类型。
shell 语言还提供了几个迭代或循环语句。在本文中,让我们通过一些示例来了解 bash 提供的循环语句。
Bash 支持以下三种循环语句
- for循环
- While 循环
- 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循环在命令行中非常有用,作为等待某些事件发生的一种方式。
- 点赞
- 收藏
- 关注作者
评论(0)