我正在尝试使用以下代码检测阿姆斯特朗数字:
declare -i INPUT=$1
arr=($(fold -w1 <<< "$INPUT"))
for index in "${!arr[@]}"
do
armstrong_sum+=$((${arr[index]}**${#arr[@]}))
done
echo "$armstrong_sum"
运行代码的命令:./armstrong_sum 9
、armstrong_sum 10
和./armstrong_sum 153
输出:9
、10
和112527
预期输出:9
、1
和153
阿姆斯特朗数是一个数字,它是它自己的数字的总和,每个数字的位数次方
更重要的是我希望能够自己调试脚本。不太确定如何在 bash 中进行调试。就像获取操作数类型并查看每一步的暂停迭代
答案1
如man bash
(强调我的)中所述
当 += 应用于已设置整数属性的变量时, value 将作为算术表达式进行计算,并添加到变量的当前值上,该值也会被计算。 当使用复合赋值将 += 应用于数组变量时(请参阅下面的数组),该变量的值不会取消设置(与使用 = 时一样),并且新值会从比数组最大索引大 1 的位置开始附加到数组中(对于索引数组)或作为附加键值对添加到关联数组中。 当应用于字符串值变量时,值会扩展并附加到变量的值中。
你显然得到了后者,即
1 + 125 + 27 = 112527
所以你有几个选择 - 要么声明armstrong_sum
为整数
#!/bin/bash
declare -i INPUT=$1
declare -i armstrong_sum=0
arr=($(fold -w1 <<< "$INPUT"))
for index in "${!arr[@]}"
do
armstrong_sum+=$(( ${arr[index]}**${#arr[@]} ))
done
echo "$armstrong_sum"
或者通过将整个表达式包围在((
and ))
ie中来确保算术评估
(( armstrong_sum += ${arr[index]}**${#arr[@]} ))
答案2
使用https://www.shellcheck.net(我用它作为语法 vim 插件,制作一个粗略的集成开发环境)
我会同意这个;
#!/bin/bash
P="$(echo -n "$1" | wc -c)"
SUM=0;
for X in $(echo "$1" | fold -w 1) ; do
SUM=$(echo "$SUM+($X^$P)" | bc );
done
echo "$SUM"
它不是“纯粹的”bash,但我发现 bash 的强大之处在于工具的广泛选择,并优先考虑易读性。
对于堆栈跟踪,如果将以下内容添加到所有脚本的顶部,它会通知您错误;
set -e
trap 'echo "ERROR: $BASH_SOURCE:$LINENO $BASH_COMMAND" >&2' ERR
它将在错误行停止脚本,输出如下
test.sh: line 7: no: command not found
ERROR: test.sh:7 no + 5
而不是(可能默默地)忽略错误。使用-x进行调试;
bash -x armstrong.sh 222
++ echo -n 222
++ wc -c
+ P=3
+ SUM=0
++ fold -w 1
++ echo 222
+ for X in $(echo "$1" | fold -w 1)
++ echo '0+(2^3)'
++ bc
+ SUM=8
+ for X in $(echo "$1" | fold -w 1)
++ echo '8+(2^3)'
++ bc
+ SUM=16
+ for X in $(echo "$1" | fold -w 1)
++ echo '16+(2^3)'
++ bc
+ SUM=24
+ echo 24
24