从先前的状态重新启动循环,如果条件不满足。

huangapple go评论61阅读模式
英文:

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&lt;=10; ++i)) ; do
    read jobstatus
    if [ &quot;$jobstatus&quot; = true ] ; then
        echo &#39;Okay lets progress&#39;
    else
        echo &#39;Nop, cant progress&#39;
        ((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
        [ &quot;$jobstatus&quot; != true ]
    do
        echo &#39;Nop, cant progress&#39;    
    done
    echo &#39;Okay lets progress&#39;

    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
        [ &quot;$jobstatus&quot; != true ]
    do
        echo &#39;Nop, cant progress&#39;
    done
    echo &#39;Okay lets progress&#39;
done
英文:

The if test should to be a loop of some sort.
For example:

for i in {1..10}
do
    while
        read jobstatus
        [ &quot;$jobstatus&quot; != true ]
    do
        echo &#39;Nop, cant progress&#39;    
    done
    echo &#39;Okay lets progress&#39;

    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
        [ &quot;$jobstatus&quot; != true ]
    do
        echo &#39;Nop, cant progress&#39;
    done
    echo &#39;Okay lets progress&#39;
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 [ &quot;$jobstatus&quot; != true ]; then
    echo &#39;Nop, cant progress&#39;
  fi

  while [ &quot;$jobstatus&quot; != &quot;true&quot; ]; do
    read jobstatus
    sleep 1
    # echo statements here if needed
  done

  echo &#39;Okay lets progress&#39;
  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 [ &quot;$i&quot; -lt 10 ] &amp;&amp; printf &#39;Enter status: &#39;; do
  IFS= read -r jobstatus
  case &quot;$jobstatus&quot; in
    true)
    i=$((i+1))
    printf &#39;Okay lets progress to %s&#39; &quot;$i&quot;;;
  *)
    printf &gt;&amp;2 &#39;Nop, cant progress because jobstatus is: %s&#39; &quot;${jobstatus:-empty}&quot;
  esac
  printf &#39;\n&#39;
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 [ &quot;$i&quot; -lt 10 ] &amp;&amp; IFS= read -r jobstatus; do
  case &quot;$jobstatus&quot; in
    true)
    i=$((i+1))
    printf &#39;Okay lets progress to %s&#39; &quot;$i&quot;;;
  *)
    printf &gt;&amp;2 &#39;Nop, cant progress because jobstatus is: %s&#39; &quot;${jobstatus:-empty}&quot;;;
  esac
  printf &#39;\n&#39;
done &lt; 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&lt;10;)); do
    read -r jobstatus
    if [[ $jobstatus == true ]]; then
        echo &quot;Okay let&#39;s progress&quot;
        (( ++truecount ))
    else
        echo &quot;Nope, can&#39;t progress&quot;
    fi
    printf &#39;%d\n&#39; &quot;$truecount&quot;
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 descriptive truecount.
  • See the accepted, and excellent, answer to Why is printf better than echo? for an explanation of why I used printf instead of echo to print the count value. (echo &quot;$truecount&quot; would probably be OK in this specific case, but echo &quot;$var&quot; doesn't work in general so I never use it. echo $var is bad. See Bash Pitfalls #14 (echo $foo).)

huangapple
  • 本文由 发表于 2023年2月20日 00:56:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75501812.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定