newprime.sh: 第 14 行: [: 0+1: 预期的整数表达式
newprime.sh: line 14: [: 0+1: integer expression expected
我的代码有什么问题?我正在尝试打印最多 n 位的素数
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
我不知道我做错了什么。如果有人能告诉我如何修复它,我将不胜感激
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
要求将参数作为单独的参数传递。引用 the POSIX standard for expr
:
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.
此处的代码将所有运算符附加到一个参数中,因此出现了问题。
因此:
c=$(expr "$c" + 1)
...不...
c=$(expr $c+1)
但是千万不要那样做。这样写更高效,更易读:
c=$(( c + 1 ))
用更少的迭代优化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
或使用函数:
#!/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 "" ]; do
# If j is a divisor of number before the end of the loop
# number is not prime, so return 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
不要使用 expr
。将你的数学表达式放在 (( ))
中(或 echo $(( ))
以打印结果),shell 将计算它。
查看 expr
输出与常规 shell 算法相比的结果:
$ expr 0+1
0+1
$ echo "$((0+1))"
1
如果两个操作数都不是整数,-eq
和 test
或单个方括号(例如 [ 1 -eq 2 ]
)会打印错误。这就是导致您出错的原因。
这是在 bash 中列出素数的一种快速简洁的方法。你可以把它放在函数或脚本中:
for ((i=2; i<="${1:?Maximum required}"; i++)); do
for ((j=2; j<i; j++)); do
((i%j)) || continue 2
done
echo "$i"
done
编辑:只是为了解释一下,如果 (([expression]))
计算为 0
,它 returns 非零(1
)(失败)。如果它的计算结果为任何其他数字(正数或负数),则它 returns 为零(真)。当一个数被 i
整除时,模数 (%
)(余数)为零。因此命令失败,我们知道它不是素数,我们可以 continue
外循环,用于下一个数字。
我的代码有什么问题?我正在尝试打印最多 n 位的素数
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
我不知道我做错了什么。如果有人能告诉我如何修复它,我将不胜感激
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
要求将参数作为单独的参数传递。引用 the POSIX standard for expr
:
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.
此处的代码将所有运算符附加到一个参数中,因此出现了问题。
因此:
c=$(expr "$c" + 1)
...不...
c=$(expr $c+1)
但是千万不要那样做。这样写更高效,更易读:
c=$(( c + 1 ))
用更少的迭代优化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
或使用函数:
#!/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 "" ]; do
# If j is a divisor of number before the end of the loop
# number is not prime, so return 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
不要使用 expr
。将你的数学表达式放在 (( ))
中(或 echo $(( ))
以打印结果),shell 将计算它。
查看 expr
输出与常规 shell 算法相比的结果:
$ expr 0+1
0+1
$ echo "$((0+1))"
1
如果两个操作数都不是整数,-eq
和 test
或单个方括号(例如 [ 1 -eq 2 ]
)会打印错误。这就是导致您出错的原因。
这是在 bash 中列出素数的一种快速简洁的方法。你可以把它放在函数或脚本中:
for ((i=2; i<="${1:?Maximum required}"; i++)); do
for ((j=2; j<i; j++)); do
((i%j)) || continue 2
done
echo "$i"
done
编辑:只是为了解释一下,如果 (([expression]))
计算为 0
,它 returns 非零(1
)(失败)。如果它的计算结果为任何其他数字(正数或负数),则它 returns 为零(真)。当一个数被 i
整除时,模数 (%
)(余数)为零。因此命令失败,我们知道它不是素数,我们可以 continue
外循环,用于下一个数字。