#!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
bash
或ksh93
用于算术评估的版本(( ... ))
,并进一步缩短代码:
#!/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
这里的所有空间都是需要的。