简体   繁体   English

Bash - 使用从文件中读取的条件中断循环

[英]Bash - break the loop with a condition that is read from a file

I am using bash to run some commands until they meet the target I set.我正在使用 bash 运行一些命令,直到它们达到我设置的目标。

Here is my code with explanation:这是我的代码和解释:

#!/bin/bash

#keep running some commands until a target is met
while : 
do
  #some executions that generate a number and write into flag.txt 

  #read the number from flag.txt and store in variable flag
  while read flag
  do
    echo $flag
  done <<< $(cat flag.txt)

  echo "hello $flag"

  #if the number from the file is >= the target I set (i.e. 0.717), then break the loop and finish the computation, otherwize, keep running.
  if [ $(echo "$flag >= 0.717" | bc) -eq 1 ]
  then
    break
  fi

done

I got some errors:我有一些错误:

0.7172
hello 
(standard_in) 1: syntax error
./test.sh: line 14: [: -eq: unary operator expected

I think this is because the 2nd while loop runs in a subshell, the value of the $flag is kept within the 2nd while loop.我认为这是因为第二个 while 循环在子 shell 中运行,$flag 的值保留在第二个 while 循环中。

  do
    echo $flag
  done <<< $(cat flag.txt)

  echo "hello $flag"

To prove this, if I change the value of $flag to a real number:为了证明这一点,如果我将 $flag 的值更改为实数:

if [ $(echo "0.72 >= 0.717" | bc) -eq 1 ]

Then I can get the correct results: Apparently, the value of $flag outside the 2nd while loop is just "blank":然后我可以得到正确的结果:显然,第二个 while 循环之外的 $flag 的值只是“空白”:

0.7172
hello 

I wonder if there is any way to work around this?我想知道是否有任何方法可以解决这个问题?

Based on your comments, it sounds like you just need to replace:根据您的评论,听起来您只需要替换:

  while read flag
  do
    echo $flag
  done <<< $(cat flag.txt)
  echo "hello $flag"
  if [ $(echo "$flag >= 0.717" | bc) -eq 1 ]; then
    break
  fi

With:和:

read flag < flag.txt
echo "hello $flag"
if test "$(echo "$flag >= 0.717" | bc)" -eq 1; then
    break
fi

Using the while loop to read every line in the file ends up leaving flag set to the empty string, because the loop doesn't terminate until read gets to the end of the file and sets flag to the empty string.使用 while 循环读取文件中的每一行最终将flag设置为空字符串,因为循环不会终止,直到read到达文件末尾并将flag设置为空字符串。 Note that, assuming the echo "hello $flag" is purely for debugging, you could simply do:请注意,假设echo "hello $flag"纯粹用于调试,您可以简单地执行以下操作:

if awk '{ exit ! ($1 >= .717)}' flag.txt; then break; fi

If I understand your question correctly, you should put your if statement within the nested loop.如果我正确理解您的问题,您应该将 if 语句放在嵌套循环中。 So that it can break when "target" is met.这样它就可以在达到“目标”时打破。 You can set another flag when this condition is met and use that flag to break out from outer loop.您可以在满足此条件时设置另一个标志,并使用该标志从外循环中跳出。

The unary operator error is due to $flag not having any value and if statement evaluates only the 2nd operand.一元运算符错误是由于 $flag 没有任何值,并且 if 语句仅计算第二个操作数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM