Bash - 循环¶
目标:在本章中,您将学会如何
使用循环;
linux, 脚本, bash, 循环
知识:
复杂性:
阅读时间: 20 分钟
bash shell 允许使用 **循环**。这些结构允许根据静态定义的值、动态值或条件 **多次**(从 0 到无穷大)执行 **一系列命令**。
while
until
for
select
无论使用哪种循环,要重复执行的命令都放在 **`do` 和 `done` 关键字之间**。
while 条件循环结构¶
`while` / `do` / `done` 结构会评估 `while` 后面跟随的命令。
如果该命令为真(`$? = 0`),则执行 `do` 和 `done` 之间的命令。然后脚本返回到开头再次评估该命令。
当评估的命令为假(`$? != 0`)时,shell 会在 `done` 之后的第一个命令处恢复脚本的执行。
`while` 条件循环结构的语法
while command
do
command if $? = 0
done
使用 `while` 条件结构的示例
while [[ -e /etc/passwd ]]
do
echo "The file exists"
done
如果评估的命令不发生变化,循环将是无限的,shell 将永远不会执行脚本后面的命令。这可能是故意的,但也可能是一个错误。所以你必须 **非常小心管理循环的命令,并找到一种方法来跳出循环**。
要跳出 `while` 循环,你必须确保被评估的命令不再为真,而这并非总是可能的。
有一些命令允许你改变循环的行为
exit
break
continue
exit 命令¶
`exit` 命令会终止脚本的执行。
`exit` 命令的语法
exit [n]
使用 `exit` 命令的示例
bash # to avoid being disconnected after the "exit 1
exit 1
echo $?
1
`exit` 命令会立即终止脚本。可以通过给出参数(从 `0` 到 `255`)来指定脚本的返回码。如果没有给出参数,脚本的最后一个命令的返回码将被传递给 `$?` 变量。
`break` / `continue` 命令¶
`break` 命令允许你通过跳到 `done` 之后的第一个命令来中断循环。
`continue` 命令允许你通过返回到 `done` 之后的第一个命令来重新开始循环。
while [[ -d / ]] INT ✘ 17s
do
echo "Do you want to continue? (yes/no)"
read ans
[[ $ans = "yes" ]] && continue
[[ $ans = "no" ]] && break
done
`true` / `false` 命令¶
`true` 命令总是返回 `true`,而 `false` 命令总是返回 `false`。
true
echo $?
0
false
echo $?
1
将它们用作循环的条件,可以实现无限循环的执行,或者禁用该循环。
示例
while true
do
echo "Do you want to continue? (yes/no)"
read ans
[[ $ans = "yes" ]] && continue
[[ $ans = "no" ]] && break
done
until 条件循环结构¶
`until` / `do` / `done` 结构会评估 `until` 后面跟随的命令。
如果该命令为假(`$? != 0`),则执行 `do` 和 `done` 之间的命令。然后脚本返回到开头再次评估该命令。
当评估的命令为真(`$? = 0`)时,shell 会在 `done` 之后的第一个命令处恢复脚本的执行。
`until` 条件循环结构的语法
until command
do
command if $? != 0
done
`until` 条件结构使用的示例
until [[ -e test_until ]]
do
echo "The file does not exist"
touch test_until
done
select 替代选择结构¶
`select` / `do` / `done` 结构允许显示一个包含多个选项的菜单并请求输入。
列表中的每个项目都有一个编号选项。当你输入一个选择时,所选的值将被赋给 `select` 之后(为此目的创建)的变量。
然后它会执行 `do` 和 `done` 之间的命令,并使用这个值。
- 变量 `PS3` 包含输入选择的提示;
- 变量 `REPLY` 将返回选择的编号。
需要 `break` 命令来退出循环。
注意
`select` 结构对于小型简单的菜单非常有用。要自定义更完整的显示,必须在 `while` 循环中使用 `echo` 和 `read` 命令。
`select` 条件循环结构的语法
PS3="Your choice:"
select variable in var1 var2 var3
do
commands
done
`select` 条件结构使用的示例
PS3="Your choice: "
select choice in coffee tea chocolate
do
echo "You have chosen the $REPLY: $choice"
done
如果运行此脚本,它会显示类似这样的内容
1) Coffee
2) Tea
3) Chocolate
Your choice : 2
You have chosen choice 2: Tea
Your choice:
for 值列表循环结构¶
`for` / `do` / `done` 结构会将列表的第一个元素赋给 `for` 之后(为此目的创建)的变量。然后它会执行 `do` 和 `done` 之间的命令,并使用这个值。然后脚本返回到开头,将列表的下一个元素赋给工作变量。当最后一个元素被使用后,shell 会在 `done` 之后的第一个命令处恢复执行。
`for` 值列表循环结构的语法
for variable in list
do
commands
done
`for` 条件结构使用的示例
for file in /home /etc/passwd /root/fic.txt
do
file $file
done
任何产生值列表的命令都可以放在 `in` 之后,使用子执行。
- 当 `IFS` 变量包含 `$' \t\n'` 时,`for` 循环将把该命令结果的 **每个单词** 作为要循环的元素列表。
- 当 `IFS` 变量包含 `$' \t\n'`(即没有空格)时,`for` 循环将读取该命令结果的每一行。
这可能是目录中的文件。在这种情况下,变量将取文件名中的每个单词作为值。
for file in $(ls -d /tmp/*)
do
echo $file
done
这可以是一个文件。在这种情况下,变量将取浏览文件时包含的每个单词作为值,从开始到结束。
cat my_file.txt
first line
second line
third line
for LINE in $(cat my_file.txt); do echo $LINE; done
first
line
second
line
third line
line
要逐行读取文件,必须修改 `IFS` 环境变量的值。
IFS=$'\t\n'
for LINE in $(cat my_file.txt); do echo $LINE; done
first line
second line
third line
作者:Antoine Le Morvan
贡献者:Steven Spencer, Ganna Zhyrnova