在 bash 中尝试简单循环时出现问题

在 bash 中尝试简单循环时出现问题
#!bin/sh
a=0
while["$a -lt 50"]
do
echo $a
a='expr $a+1'
done

我得到了无限的回声expr $a+1。我究竟做错了什么?

答案1

您的脚本有语法错误。您可以使用以下命令检查 shell 脚本中是否存在有问题的结构外壳检查在线的。

这会告诉你

Line 3:
while["$a -lt 50"]
^-- SC1009: The mentioned parser error was in this while loop.
     ^-- SC1035: You need a space after the [ and before the ].
     ^-- SC1069: You need a space before the [.
     ^-- SC1073: Couldn't parse this test expression.
                  ^-- SC1020: You need a space before the ].
                  ^-- SC1072: Missing space before ]. Fix any mentioned problems and try again.

通过更改解决空间问题

while["$a -lt 50"]

进入

while [ "$a -lt 50" ]

相反,会给你以下内容:

Line 3:
while [ "$a -lt 50" ]
           ^-- SC2157: Argument to implicit -n is always true due to literal strings.

Line 6:
a='expr $a+1'
  ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.

报告的第一个问题是关于 string 的"$a -lt 50"。事实上,你不想在这里有这样的字符串,你想要"$a" -lt 50.顺便说一句,由于字符串总是“true”,这就是为什么你的循环是无限的(如果语法错误已修复)。

第二个问题是由于检查器检测到变量$a单引号字符串内的变量,该变量不会扩展到其值(这就是为什么打印的字符串是expr $a+1)。解决方案不是将其更改为双引号,因为这只会为您提供相同的字符串,但值会扩展。您想要执行该expr命令。

通过将单引号更改为反引号来做到这一点。

您的脚本现在如下所示:

#!bin/sh
a=0
while [ "$a" -lt 50 ]
do
echo $a
a=`expr $a+1`
done

...而 ShellCheck 仍然不高兴:

Line 6:
a=`expr $a+1`
  ^-- SC2006: Use $(..) instead of legacy `..`.
   ^-- SC2003: expr is antiquated. Consider rewriting this using $((..)), ${} or [[ ]].

新的 shell 代码确实应该使用$( ... )反引号而不是反引号。此外,它还会向您发出有关使用 的警告expr,该警告已过时。

该行可以重写为

a="$(( a + 1 ))"

最终版本(加上缩进和对 -line 的修复#!):

#!/bin/sh

a=0
while [ "$a" -lt 50 ]; do
  echo $a
  a="$(( a + 1 ))"
done

bashksh93用于算术评估的版本(( ... )),并进一步缩短代码:

#!/bin/bash

a=0
while (( a < 50 )); do
  echo "$(( a++ ))"
done

答案2

更正原件

#!bin/sh
a=0
while [ "$a" -lt "50" ] # mind the spaces and double quote the variable
do
echo "$a"
a=`expr $a + 1` # replace single quotes with backticks, mind the space between $a and 1
done

改进

#!bin/bash  # Why not put bash here? sh may not always be linked to bash
a=0
while [ "$a" -lt "50" ] # mind the spaces and double quote the variable
do
echo "$a"
a=$(expr $a + 1) # replace legacy backticks with $()
# Or better you can even use double parenthesis which allows you do
# (( a++ )) , note the C style increment operator here
done

笔记要检查脚本,请使用[外壳检查]

答案3

或者总是使用 for 循环:

for ((a=0;a < 50; ++a))
do echo $a
done

快速、直接;不需要反引号执行。

答案4

#!bin/sh
a=0
while [ $a -lt 50 ]
do
  echo $a
  a=$((a+1))
done

这里的所有空间都是需要的。

相关内容