bash:期望用 += 进行数字加法。不确定操作数是否是数字

bash:期望用 += 进行数字加法。不确定操作数是否是数字

我正在尝试使用以下代码检测阿姆斯特朗数字:

declare -i INPUT=$1


arr=($(fold -w1 <<< "$INPUT"))
for index in "${!arr[@]}"
do
  armstrong_sum+=$((${arr[index]}**${#arr[@]}))
done


echo "$armstrong_sum"

运行代码的命令:./armstrong_sum 9armstrong_sum 10./armstrong_sum 153

输出:910112527

预期输出:91153

阿姆斯特朗数是一个数字,它是它自己的数字的总和,每个数字的位数次方

更重要的是我希望能够自己调试脚本。不太确定如何在 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

相关内容