英文:
Restart loop from the previous state if a condition is not met
问题
问题陈述是,如果条件不为真,它应该“停止”for循环,或者除非满足该值,否则不应继续。
假设在for循环中有一个输入语句,它可以是true/false或布尔语句,该循环打印1到10。
如果条件在第5次迭代中变为假,它应该保持在第5次迭代,直到布尔值返回真。
for i in {1..10}
do
read jobstatus
if [ "$jobstatus" = true ] ; then
echo '好的,让我们继续'
else
echo '不行,无法继续'
((i--))
fi
echo $i
done
我尝试过创建这样的代码,还通过创建充当“标志”的文件来进行检查,但似乎无法“停止”进度。我不想打破循环,我只想使其保持在特定迭代,直到状态发生变化。就像如果作业状态在i=5时变为假,那么i应该保持在5,直到作业状态变为真。(我打算在每个输入中检查作业状态)
英文:
The problem statement is that if a condition is not true, it should "stop" the for loop or should not progress unless that value is met.
Lets say that there is an input statement of true/false or a boolean statement in a for loop that prints to 1 to 10.
If the condition goes false in the the 5th iteration, it should stay at 5th iteration until the boolean returns true.
for i in {1..10}
do
read jobstatus
# echo $i
if [ "$jobstatus" = true ] ; then
echo 'Okay lets progress'
else
echo 'Nop, cant progress'
((i--))
# continue
#print $i
fi
echo $i
done
I have tried making codes such as this, also checked it via making files that were acting as "flags" But I cant seem to "stop" the progression. I dont want to break the loop, I just want to make it stay at that specific iteration until and unless the state changes.
Like if the job status goes falses at i=5, i should stay at 5 unless jobstatus gets to true. ( I intend to check the jobstatus at each input)
答案1
得分: 2
你可以像这样组织循环:
#!/bin/bash
i=0
while test "$i" -lt 10; do
while read jobstatus && test "$jobstatus" != true; do
echo "无法继续。jobstatus = $jobstatus" >&2
done
if test "$jobstatus" = true; then
echo "好的,让我们继续到第 $((++i)) 步"
else
echo 意外的输入结束 >&2
exit 1
fi
echo "$i"
done
英文:
You could structure the loops something like:
#!/bin/bash
i=0
while test "$i" -lt 10; do
while read jobstatus && test "$jobstatus" != true; do
echo "can't progress. jobstatus = $jobstatus" >&2
done
if test "$jobstatus" = true; then
echo "Okay lets progress to step $((++i))"
else
echo Unexpected End of input >&2
exit 1
fi
echo "$i"
done
答案2
得分: 1
使用C风格的for循环:
#!/bin/bash
for ((i=1; i<=10; ++i)) ; do
read jobstatus
if [ "$jobstatus" = true ] ; then
echo '好的,让我们继续'
else
echo '不行,无法继续'
((i--))
fi
echo $i
done
英文:
Use a C-style for-loop:
#!/bin/bash
for ((i=1; i<=10; ++i)) ; do
read jobstatus
if [ "$jobstatus" = true ] ; then
echo 'Okay lets progress'
else
echo 'Nop, cant progress'
((i--))
fi
echo $i
done
答案3
得分: 0
The if
test should to be a loop of some sort.
For example:
if条件测试应该是某种循环。
例如:
```bash
for i in {1..10}
do
while
read jobstatus
[ "$jobstatus" != true ]
do
echo 'Nop, cant progress'
done
echo 'Okay lets progress'
echo $i
done
If you want to repeat the other for
commands (ie. the echo $i
statement here) until the test succeeds, they should go inside the loop too. For example:
如果要重复执行其他 for
命令(即这里的 echo $i
语句),直到测试成功,它们也应该放在循环内。例如:
for i in {1..10}
do
while
echo $i
read jobstatus
[ "$jobstatus" != true ]
do
echo 'Nop, cant progress'
done
echo 'Okay lets progress'
done
英文:
The if
test should to be a loop of some sort.
For example:
for i in {1..10}
do
while
read jobstatus
[ "$jobstatus" != true ]
do
echo 'Nop, cant progress'
done
echo 'Okay lets progress'
echo $i
done
If you want to repeat the other for
commands (ie. the echo $i
statement here) until the test succeeds, they should go inside the loop too. For example:
for i in {1..10}
do
while
echo $i
read jobstatus
[ "$jobstatus" != true ]
do
echo 'Nop, cant progress'
done
echo 'Okay lets progress'
done
</details>
# 答案4
**得分**: 0
这可能是您正在寻找的内容:
```bash
for i in {1..10}; do
read jobstatus
if [ "$jobstatus" != true ]; then
echo '不行,无法继续'
fi
while [ "$jobstatus" != "true" ]; do
read jobstatus
sleep 1
# 如果需要,可以在这里添加 echo 语句
done
echo '好的,让我们继续'
echo $i
done
无需减少 i
,这也避免了过于频繁地检查 jobstatus
状态,从而节省了不必要的资源。
英文:
This may be what you are looking for:
for i in {1..10}; do
read jobstatus
if [ "$jobstatus" != true ]; then
echo 'Nop, cant progress'
fi
while [ "$jobstatus" != "true" ]; do
read jobstatus
sleep 1
# echo statements here if needed
done
echo 'Okay lets progress'
echo $i
done
No need to decrement i
, this also avoids checking the status of jobstatus
too often potentially consuming an unnecessary amount of resources.
答案5
得分: 0
以下是代码的翻译部分:
#!/bin/sh
i=0
while [ "$i" -lt 10 ] && printf 'Enter status: '; do
IFS= read -r jobstatus
case "$jobstatus" in
true)
i=$((i+1))
printf 'Okay lets progress to %s' "$i";;
*)
printf >&2 'Nop, cant progress because jobstatus is: %s' "${jobstatus:-empty}"
esac
printf '\n'
done
#!/bin/sh
i=0
while [ "$i" -lt 10 ] && IFS= read -r jobstatus; do
case "$jobstatus" in
true)
i=$((i+1))
printf 'Okay lets progress to %s' "$i";;
*)
printf >&2 'Nop, cant progress because jobstatus is: %s' "${jobstatus:-empty}";;
esac
printf '\n'
done < file.txt
Okay lets progress to 1
Okay lets progress to 2
Okay lets progress to 3
Okay lets progress to 4
Okay lets progress to 5
Nop, cant progress because jobstatus is: false
Nop, cant progress because jobstatus is: foo
Nop, cant progress because jobstatus is: bar
Nop, cant progress because jobstatus is: baz
Nop, cant progress because jobstatus is: empty
Okay lets progress to 6
Okay lets progress to 7
Okay lets progress to 8
Okay lets progress to 9
Nop, cant progress because jobstatus is: qux
Nop, cant progress because jobstatus is: empty
Okay lets progress to 10
英文:
With an interactive user input, Maybe something like this:
#!/bin/sh
i=0
while [ "$i" -lt 10 ] && printf 'Enter status: '; do
IFS= read -r jobstatus
case "$jobstatus" in
true)
i=$((i+1))
printf 'Okay lets progress to %s' "$i";;
*)
printf >&2 'Nop, cant progress because jobstatus is: %s' "${jobstatus:-empty}"
esac
printf '\n'
done
Using a text file for the input, to test the script.
The file.txt
true
true
true
true
true
false
foo
bar
baz
true
true
true
true
qux
true
false
The script:
#!/bin/sh
i=0
while [ "$i" -lt 10 ] && IFS= read -r jobstatus; do
case "$jobstatus" in
true)
i=$((i+1))
printf 'Okay lets progress to %s' "$i";;
*)
printf >&2 'Nop, cant progress because jobstatus is: %s' "${jobstatus:-empty}";;
esac
printf '\n'
done < file.txt
Output:
Okay lets progress to 1
Okay lets progress to 2
Okay lets progress to 3
Okay lets progress to 4
Okay lets progress to 5
Nop, cant progress because jobstatus is: false
Nop, cant progress because jobstatus is: foo
Nop, cant progress because jobstatus is: bar
Nop, cant progress because jobstatus is: baz
Nop, cant progress because jobstatus is: empty
Okay lets progress to 6
Okay lets progress to 7
Okay lets progress to 8
Okay lets progress to 9
Nop, cant progress because jobstatus is: qux
Nop, cant progress because jobstatus is: empty
Okay lets progress to 10
答案6
得分: 0
请尝试这个经过 Shellcheck 清理过的 Bash 代码:
#! /bin/bash -p
for ((truecount=0; truecount<10;)); do
read -r jobstatus
if [[ $jobstatus == true ]]; then
echo "好的,让我们继续"
(( ++truecount ))
else
echo "不行,无法继续"
fi
printf '%d\n' "$truecount"
done
- 与原始代码的主要变化是它只在 'true' 状态下前进,而不是总是前进并在非 'true' 状态下后退。一般来说,最好只在一个地方修改循环变量。
- 由于代码不仅仅是在一个序列中前进,我用有描述性的 'truecount' 替代了无意义的 'i'。
- 请参考 为什么 printf 比 echo 好? 中的已被接受和优秀的答案,以了解为什么我使用
printf
而不是echo
来打印计数值。 (echo "$truecount"
在这种特定情况下可能也可以,但echo "$var"
在一般情况下不起作用,因此我从不使用它。echo $var
是有问题的。请参阅 Bash 陷阱 #14 (echo $foo)。)
英文:
Try this Shellcheck-clean Bash code:
#! /bin/bash -p
for ((truecount=0; truecount<10;)); do
read -r jobstatus
if [[ $jobstatus == true ]]; then
echo "Okay let's progress"
(( ++truecount ))
else
echo "Nope, can't progress"
fi
printf '%d\n' "$truecount"
done
- The major change from the original code is that it advances only on 'true' status instead of always advancing and stepping back on non-'true' status. In general, it's best if you can modify a loop variable in only one place.
- Since the code isn't just stepping through a sequence, I replaced the meaningless
i
with the descriptivetruecount
. - See the accepted, and excellent, answer to Why is printf better than echo? for an explanation of why I used
printf
instead ofecho
to print the count value. (echo "$truecount"
would probably be OK in this specific case, butecho "$var"
doesn't work in general so I never use it.echo $var
is bad. See Bash Pitfalls #14 (echo $foo).)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论