9.5. 中断和继续

9.5.1. break 内置命令

break 语句用于在当前循环正常结束之前退出循环。当您事先不知道循环需要执行多少次时,可以使用它,例如,因为它取决于用户输入。

下面的示例演示了一个可以被中断的 while 循环。这是经过略微改进的版本,来自wisdom.sh脚本,来自 第 9.2.2.3 节

#!/bin/bash

# This script provides wisdom
# You can now exit in a decent way.

FORTUNE=/usr/games/fortune

while true; do
echo "On which topic do you want advice?"
echo "1.  politics"
echo "2.  startrek"
echo "3.  kernelnewbies"
echo "4.  sports"
echo "5.  bofh-excuses"
echo "6.  magic"
echo "7.  love"
echo "8.  literature"
echo "9.  drugs"
echo "10. education"
echo

echo -n "Enter your choice, or 0 for exit: "
read choice
echo

case $choice in
     1)
     $FORTUNE politics
     ;;
     2)
     $FORTUNE startrek
     ;;
     3)
     $FORTUNE kernelnewbies
     ;;
     4)
     echo "Sports are a waste of time, energy and money."
     echo "Go back to your keyboard."
     echo -e "\t\t\t\t -- \"Unhealthy is my middle name\" Soggie."
     ;;
     5)
     $FORTUNE bofh-excuses
     ;;
     6)
     $FORTUNE magic
     ;;
     7)
     $FORTUNE love
     ;;
     8)
     $FORTUNE literature
     ;;
     9)
     $FORTUNE drugs
     ;;
     10)
     $FORTUNE education
     ;;
     0)
     echo "OK, see you!"
     break
     ;;
     *)
     echo "That is not a valid choice, try a number from 0 to 10."
     ;;
esac  
done

请注意,break 退出循环,而不是脚本。这可以通过在脚本末尾添加一个 echo 命令来演示。当用户输入导致 break 执行的输入(当用户输入 “0” 时),这个 echo 也将被执行。

在嵌套循环中,break 允许指定要退出的循环。更多信息请参阅 Bash info 页面。

9.5.2. continue 内置命令

continue 语句恢复封闭的 forwhileuntilselect 循环的迭代。

当在 for 循环中使用时,控制变量取列表中下一个元素的值。另一方面,当在 whileuntil 结构中使用时,执行从循环顶部的 TEST-COMMAND 处恢复。

9.5.3. 示例

在以下示例中,文件名被转换为小写。如果不需要进行转换,continue 语句会重新开始执行循环。这些命令不会占用太多系统资源,而且很可能,类似的问题可以使用 sedawk 解决。然而,当执行繁重任务时,了解这种结构是有用的,当测试插入到脚本中的正确位置时,这些任务甚至可能是不必要的,从而节省系统资源。

[carol@octarine ~/test] cat tolower.sh
#!/bin/bash

# This script converts all file names containing upper case characters into file# names containing only lower cases.

LIST="$(ls)"

for name in "$LIST"; do

if [[ "$name" != *[[:upper:]]* ]]; then
continue
fi

ORIG="$name"
NEW=`echo $name | tr 'A-Z' 'a-z'`

mv "$ORIG" "$NEW"
echo "new name for $ORIG is $NEW"
done

这个脚本至少有一个缺点:它会覆盖现有文件。Bash 的noclobber选项仅在发生重定向时才有用。mv 命令的-b选项提供了更高的安全性,但仅在发生一次意外覆盖时才是安全的,正如本测试所演示的那样

[carol@octarine ~/test] rm *

[carol@octarine ~/test] touch test Test TEST

[carol@octarine ~/test] bash -x tolower.sh
++ ls
+ LIST=test
Test
TEST
+ [[ test != *[[:upper:]]* ]]
+ continue
+ [[ Test != *[[:upper:]]* ]]
+ ORIG=Test
++ echo Test
++ tr A-Z a-z
+ NEW=test
+ mv -b Test test
+ echo 'new name for Test is test'
new name for Test is test
+ [[ TEST != *[[:upper:]]* ]]
+ ORIG=TEST
++ echo TEST
++ tr A-Z a-z
+ NEW=test
+ mv -b TEST test
+ echo 'new name for TEST is test'
new name for TEST is test

[carol@octarine ~/test] ls -a
./  ../  test  test~

trtextutils 软件包的一部分;它可以执行各种字符转换。