在我正在编写的脚本中,我试图退出第二个嵌套while循环,continue语句似乎被简单地忽略了,我不确定确切的原因。
来自手册:
continue [n]:
Resume the next iteration of the enclosing for, while, until, or select loop. If n is specified,
resume at the nth enclosing loop. n must be ≥ 1. If n is greater than the number of enclosing
loops, the last enclosing loop (the ``top-level'' loop) is resumed. The return value is 0 unless n
is not greater than or equal to 1.
举例说明我的问题(ex1.sh
(:
#!/bin/bash
printf "%dn" {1..3} | while read i; do
printf "%dn" {1..3} | while read j; do
sum=$(expr $i + $j)
echo "$i + $j = $sum"
[ $sum -ge 5 ] && echo continue && continue 2
done
echo 'should only see this for first cycle of i (2+3 >= 5)'
done
ex1.sh
:输出
1 + 1 = 2
1 + 2 = 3
1 + 3 = 4
should only see this for first cycle of i (2+3 >= 5)
2 + 1 = 3
2 + 2 = 4
2 + 3 = 5
continue
should only see this for first cycle of i (2+3 >= 5)
3 + 1 = 4
3 + 2 = 5
continue
3 + 3 = 6
continue
should only see this for first cycle of i (2+3 >= 5)
为什么continue 2
被忽略?它清楚地回响出";"继续";,并且通过使用set -x
运行跟踪来确认继续运行的事实
printf
的使用显然是愚蠢的ex1.sh
,但它再现了我在while read x...
循环中继续工作的问题。
A for循环按预期工作(ex2.sh
(:
#!/bin/bash
for i in {1..3}; do
for j in {1..3}; do
sum=$(expr $i + $j)
echo "$i + $j = $sum"
[ $sum -ge 5 ] && echo continue && continue 2
done
echo 'should only see this for first cycle of i (2+3 >= 5)'
done
ex2.sh
:的输出
1 + 1 = 2
1 + 2 = 3
1 + 3 = 4
should only see this for first cycle of i (2+3 >= 5)
2 + 1 = 3
2 + 2 = 4
2 + 3 = 5
continue
3 + 1 = 4
3 + 2 = 5
continue
那么,为什么ex1.sh
似乎忽略了continue 2
内置,而ex2.sh
的行为却如预期的那样呢?
修正了我自己感谢M.Nejat Aydin的第一个例子:
#!/bin/bash
while read i; do
while read j; do
sum=$(expr $i + $j)
echo "$i + $j = $sum"
[ $sum -ge 5 ] && echo continue && continue 2
done < <(printf "%dn" {1..3})
echo 'should only see this for first cycle of i (2+3 >= 5)'
done < <(printf "%dn" {1..3})
问题是管道创建了子shell,所以我的continue语句按照手册的预期运行,在子shell知道的最外层循环处继续。
您的while
循环没有嵌套。它们在不同的潜艇里运行。continue
无法从父shell继续。管道(|
(创建一个子shell。另一方面,由于两个while
都在同一个shell中运行,因此下面的版本应该可以正常工作:
while read i; do
while read j; do
sum=$(expr $i + $j)
echo "$i + $j = $sum"
[ $sum -ge 5 ] && echo continue && continue 2
done < <(printf "%dn" {1..3})
echo 'should only see this for first cycle of i (2+3 >= 5)'
done < <(printf "%dn" {1..3})