循环语句

for…in…do…done

命令格式:

for var in val1 val2 val3
do
   语句1
   语句2
   ...
done

示例1,输出a 2 cc,每个元素一行:

for i in a 2 cc
do
   echo $i
done

示例2,输出当前路径下的所有文件名,每个文件名一行:

for file in `ls`
do
   echo $file
done

示例3,输出1-10

for i in $(seq 1 10)
do
   echo $i
done

# 步长为2的话:for i in $(seq 1 2 10)

示例4,使用{1..10} 或者 {a..z}

for i in {a..z}
do
   echo $i
done

for ((…;…;…)) do…done

命令格式:(和c++一样)

for ((expression; condition; expression))
do
   语句1
   语句2
done

示例,输出1-10,每个数占一行:

for ((i=1; i<=10; i++))
do
   echo $i
done

while…do…done循环

命令格式:

while condition
do
   语句1
   语句2
   ...
done

示例,文件结束符为Ctrl+d,输入文件结束符后read指令返回false。

while read name
do
   echo $name
done

until…do…done循环

当条件为真时结束。

命令格式:

until condition
do
   语句1
   语句2
   ...
done

示例,当用户输入yes或者YES时结束,否则一直等待读入。

until [ "${word}" == "yes" ] || [ "${word}" == "YES" ]
do
   read -p "Please input yes/YES to stop this program: " word
done

break命令

跳出当前一层循环,注意与C/C++不同的是:break不能跳出case语句。

示例

while read name
do
   for ((i=1;i<=10;i++))
   do
       case $i in
           8)
               break
               ;;
           *)
               echo $i
               ;;
       esac
   done
done

该示例每读入非EOF的字符串,会输出一遍1-7。

该程序可以输入Ctrl+d文件结束符来结束,也可以直接用Ctrl+c杀掉该进程。

continue命令

跳出当前循环。

示例:

for ((i=1;i<=10;i++))
do
   if [ `expr $i % 2` -eq 0 ]
   then
       continue
   fi
   echo $i
done

该程序输出1-10中的所有奇数。

死循环的处理方式

如果AC Terminal可以打开该程序,则输入Ctrl+c即可。

否则可以直接关闭进程:

  • 使用top命令找到进程的PID
  • 输入kill -9 PID即可关掉此进程
💡两种常见的死循环写法
while true  # 或写成 while :
do
    echo "running..."
    sleep 1
done
for ((;;))  # C 风格省略全部表达式
do
    echo "running..."
    sleep 1
done

服务类程序(如后面 thrift 课的匹配服务器)就是靠死循环常驻后台的,配合 tmux 挂起会话运行。

ℹ️break N 与 continue N:一次跳出多层

break 和 continue 后面都可以跟一个正整数 N(默认为 1):

  • break N:跳出 N 层循环——上文的“break不能跳出case语句”指它只对循环层计数,case 本身不算一层;
  • continue N:结束倒数第 N 层循环的本次迭代。例如双重循环内层写 continue 2,则跳过外层本轮剩余语句、直接进入外层下一次循环。
for ((i = 1; i <= 3; i++))
do
    for ((j = 1; j <= 3; j++))
    do
        if [ $j -eq 2 ]
        then
            continue 2  # 直接进入外层下一轮
        fi
        echo "\(i-\)j"
    done
done
# 输出 1-1 / 2-1 / 3-1

项目分区导航判断语句 ⬅️ | 17-循环语句 | ➡️ 函数