如何在bash中检查一个数字是否超出动态范围?

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

How to check if a number is outside a dynamic range in bash?

问题

我有一个披萨生成器的代码。它允许用户选择披萨的大小和来自侧边文件的配料列表。

我正在尝试验证用户的输入,以便输入一个介于1和来自侧边文件的配料数量之间的数字。

我从文件中获取行数并将其存储在一个变量中,使用以下命令:

numtop=$( cat Toppings | wc -l );

然后,我读取用户的输入并使用if语句进行检查:

read topp
if [[ "$topp" < 1 || "$topp" > "$numtop" ]]; then
     echo "请输入1到" $numtop
else
     echo "好选择"
fi

但它只允许我输入1或来自$numtop变量的数字。我不明白为什么这不起作用。

英文:

I have a pizza builder code. It gives the user to chose a pizza size and a list of toppings from a side file.
I'm trying to validate users input so it can enter a number between 1 and the amount of toppings from the side file.

I'm getting the number of rows from the file and set it to a variable using wc
numtop=$( cat Toppings | wc -l );

After that I read the users input and run a check using if

read topp
if [[ &quot;$topp&quot; &lt; 1 || &quot;$topp&quot; &gt; &quot;$numtop&quot; ]]; then
     echo &quot;Enter from 1 to &quot; $numtop
else
     echo &quot;Good choice&quot;
fi

But it allows me to enter only 1 or the number from my $numtop variable. I can't understand why this doesn't work.

答案1

得分: 1

你需要在算术表达式中使用 (( )),类似于:

#!/usr/bin/env bash

numtop="$(wc -l < Toppings)"

while read -rp "输入 1 到 $numtop 之间的数字:" topp; do
  if (( topp < 1 || topp > numtop )); then
    echo "请输入 1 到 $numtop 之间的数字"
  else
    echo "选择有效"
    break
  fi
done

编辑:根据 @jhnc 的建议,如果输入类似于:a[$(date>/dev/tty)],1(第一个答案可能会出错),首先检查输入的值是否严格为数字。

#!/usr/bin/env bash

##: 还要测试 Toppings 是否为空文件
##: 或者只需测试 $numtop 的值。
numtop="$(wc -l < Toppings)"

while printf '输入 1 到 %s 之间的数字:' "$numtop"; do
  read -r topp
  case $topp in
    ('')
      printf '输入为空\n' >&2
       ;;
    (*[!0123456789]*)
       printf '%s 中有非数字字符\n' "$topp" >&2
       ;;
    (*)
      if (( topp < 1 || topp > numtop )); then
        printf '你输入了 %s\n' "$topp"  >&2
      else
        printf '你输入了 %s,选择有效!\n' "$topp" &&
        break
      fi
     ;;
  esac
done
  • [[ ... ]] 中使用的 &lt;&gt; 不是用于 bash 中的算术表达式,参见 help test。它们用于测试字符串的字典顺序。

  • 请参阅在线 bash 手册中的 Conditional Constructs,查找 [[ expression ]],其中指出:“在与 [[ 一起使用时,‘<’ 和 ‘>’ 运算符使用当前区域设置进行字典排序。”

  • 请参阅 How can I tell whether a variable contains a valid number?

  • numtop=$( cat Toppings | wc -l );UUOC 的一种形式。

英文:

You need to use the (( )) for arithmetic expression, something like:

#!/usr/bin/env bash

numtop=&quot;$(wc -l &lt; Toppings)&quot;

while read -rp &quot;Enter from 1 to  $numtop &quot; topp; do
  if (( topp &lt; 1 || topp &gt; numtop )); then
    echo &quot;Enter from 1 to $numtop&quot;
  else
    echo &quot;Good choice&quot;
    break
  fi
done

EDIT: as per @jhnc, Given the input is something like: a[$(date&gt;/dev/tty)],1 (the first answer breaks badly) check the value of input first if it is strictly numeric.

#!/usr/bin/env bash

##: Test also if Toppings is empty if it is a file
##: or just test the value of $numtop.
numtop=&quot;$(wc -l &lt; Toppings)&quot;

while printf &#39;Enter from 1 to %s &#39; &quot;$numtop&quot;; do
  read -r topp
  case $topp in
    (&#39;&#39;)
      printf &#39;input is empty\n&#39; &gt;&amp;2
       ;;
    (*[!0123456789]*)
       printf &#39;%s has a non-digit somewhere in it\n&#39; &quot;$topp&quot; &gt;&amp;2
       ;;
    (*)
      if (( topp &lt; 1 || topp &gt; numtop )); then
        printf &#39;You entered %s\n&#39; &quot;$topp&quot;  &gt;&amp;2
      else
        printf &#39;You entered %s Good choice!\n&#39; &quot;$topp&quot; &amp;&amp;
        break
      fi
     ;;
  esac
done

huangapple
  • 本文由 发表于 2023年6月18日 17:41:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76499896.html
匿名

发表评论

匿名网友

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

确定