[英]newprime.sh: line 14: [: 0+1: integer expression expected
echo Enter Number
read num
for (( i=2; $i <= $num ; i++ ))
do
c=0
for (( j=2; $j <= $i ; j++))
do
mod=$(($i % $j))
if [ "$mod" -eq 0 ]
then
c=`expr $c+1`
fi
done
if [ "$c" -eq 1 ]
then
echo $c
fi
done
I don't have any idea what I'm doing wrong.我不知道我做错了什么。 If someone could tell me how to fix it I would be thankful如果有人能告诉我如何解决它,我将不胜感激
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1+1+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
expr
requires parameters to be passed as separate arguments. expr
要求参数作为单独的 arguments 传递。 Quoting the POSIX standard for expr
:引用expr
的 POSIX 标准:
The application shall ensure that each of the expression operator symbols [...] and the symbols integer and string in the table are provided as separate arguments to expr.应用程序应确保表中的每个表达式运算符符号 [...] 和符号 integer 和字符串作为单独的 arguments 提供给 expr。
The code here is appending all the operators into a single argument, hence your problem.这里的代码将所有运算符附加到一个参数中,因此您的问题。
Thus:因此:
c=$(expr "$c" + 1)
...NOT... ...不是...
c=$(expr $c+1)
But don't do that at all.但千万不要这样做。 It's more efficient and more readable to write:写起来更高效、更易读:
c=$(( c + 1 ))
Optimized with less iterations POSIX shell version:优化了更少的迭代 POSIX shell 版本:
#!/usr/bin/env sh
printf %s 'Enter Number: '
read -r num
i=1
while [ "$i" -le "$num" ]; do
c=0
j=2
# Stop checking division when divisor power 2 is greater than number
# or we identifed a divisor
while [ "$((j * j))" -le "$i" ] && [ "$c" -eq 0 ]; do
c=$((i % j == 0))
j=$((j + 1))
done
if [ "$c" -eq 0 ]; then
printf '%s\n' "$i"
fi
i=$((i + 2))
done
Or using a function:或使用 function:
#!/usr/bin/env sh
is_prime() {
j=2
# Check j is a divisor of argument number, while j^2 is less than number
while [ "$((j * j))" -le "$1" ]; do
# If j is a divisor of number before the end of the loop
# number is not prime, so return 1
[ "$(($1 % j))" -eq 0 ] && return 1
j=$((j + 1))
done
}
printf %s 'Enter Number: '
read -r num
i=1
while [ "$i" -le "$num" ]; do
if is_prime "$i"; then
printf '%s\n' "$i"
fi
i=$((i + 2))
done
Don't use expr
.不要使用expr
。 Put your mathematical expression inside (( ))
(or echo $(( ))
to print the result), and the shell will evaluate it.将您的数学表达式放入(( ))
(或echo $(( ))
以打印结果),shell 将评估它。
See what the expr
output looks like, vs regular shell arithmetic:查看expr
output 与常规 shell 算法的对比:
$ expr 0+1
0+1
$ echo "$((0+1))"
1
-eq
with test
, or single square brackets (eg [ 1 -eq 2 ]
) prints an error if both operands aren't integers. -eq
如果两个操作数都不是整数,则带有test
或单方括号(例如[ 1 -eq 2 ]
)会打印错误。 That's what's causing your error.这就是导致您的错误的原因。
Here's a fast and concise way to list primes in bash.这是列出 bash 中素数的快速简洁的方法。 You can put it in a function or script:您可以将其放入 function 或脚本中:
for ((i=2; i<="${1:?Maximum required}"; i++)); do
for ((j=2; j<i; j++)); do
((i%j)) || continue 2
done
echo "$i"
done
edit: Just to explain something, if (([expression]))
evaluates to 0
, it returns non-zero ( 1
) (failure).编辑:只是为了解释一些事情,如果(([expression]))
评估为0
,它返回非零( 1
)(失败)。 If it evaluates to any other number (positive or negative), it returns zero (true).如果计算结果为任何其他数字(正数或负数),则返回零 (true)。 When a number divides evenly in to i
, the modulo ( %
) (remainder) is zero.当一个数除以i
时,模( %
)(余数)为零。 Hence the command fails, we know it's not prime, and we can continue
the outer loop, for the next number.因此命令失败,我们知道它不是素数,我们可以continue
外循环,以获得下一个数字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.