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

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

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

问题

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

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

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

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

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

  1. read topp
  2. if [[ "$topp" < 1 || "$topp" > "$numtop" ]]; then
  3. echo "请输入1到" $numtop
  4. else
  5. echo "好选择"
  6. 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

  1. read topp
  2. if [[ &quot;$topp&quot; &lt; 1 || &quot;$topp&quot; &gt; &quot;$numtop&quot; ]]; then
  3. echo &quot;Enter from 1 to &quot; $numtop
  4. else
  5. echo &quot;Good choice&quot;
  6. 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

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

  1. #!/usr/bin/env bash
  2. numtop="$(wc -l < Toppings)"
  3. while read -rp "输入 1 到 $numtop 之间的数字:" topp; do
  4. if (( topp < 1 || topp > numtop )); then
  5. echo "请输入 1 到 $numtop 之间的数字"
  6. else
  7. echo "选择有效"
  8. break
  9. fi
  10. done

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

  1. #!/usr/bin/env bash
  2. ##: 还要测试 Toppings 是否为空文件
  3. ##: 或者只需测试 $numtop 的值。
  4. numtop="$(wc -l < Toppings)"
  5. while printf '输入 1 到 %s 之间的数字:' "$numtop"; do
  6. read -r topp
  7. case $topp in
  8. ('')
  9. printf '输入为空\n' >&2
  10. ;;
  11. (*[!0123456789]*)
  12. printf '%s 中有非数字字符\n' "$topp" >&2
  13. ;;
  14. (*)
  15. if (( topp < 1 || topp > numtop )); then
  16. printf '你输入了 %s\n' "$topp" >&2
  17. else
  18. printf '你输入了 %s,选择有效!\n' "$topp" &&
  19. break
  20. fi
  21. ;;
  22. esac
  23. 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:

  1. #!/usr/bin/env bash
  2. numtop=&quot;$(wc -l &lt; Toppings)&quot;
  3. while read -rp &quot;Enter from 1 to $numtop &quot; topp; do
  4. if (( topp &lt; 1 || topp &gt; numtop )); then
  5. echo &quot;Enter from 1 to $numtop&quot;
  6. else
  7. echo &quot;Good choice&quot;
  8. break
  9. fi
  10. 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.

  1. #!/usr/bin/env bash
  2. ##: Test also if Toppings is empty if it is a file
  3. ##: or just test the value of $numtop.
  4. numtop=&quot;$(wc -l &lt; Toppings)&quot;
  5. while printf &#39;Enter from 1 to %s &#39; &quot;$numtop&quot;; do
  6. read -r topp
  7. case $topp in
  8. (&#39;&#39;)
  9. printf &#39;input is empty\n&#39; &gt;&amp;2
  10. ;;
  11. (*[!0123456789]*)
  12. printf &#39;%s has a non-digit somewhere in it\n&#39; &quot;$topp&quot; &gt;&amp;2
  13. ;;
  14. (*)
  15. if (( topp &lt; 1 || topp &gt; numtop )); then
  16. printf &#39;You entered %s\n&#39; &quot;$topp&quot; &gt;&amp;2
  17. else
  18. printf &#39;You entered %s Good choice!\n&#39; &quot;$topp&quot; &amp;&amp;
  19. break
  20. fi
  21. ;;
  22. esac
  23. 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:

确定