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(強調)に規定されているように

整数属性が設定された変数に+ =を適用すると、値は算術式として評価され、変数の現在の値に追加され、この値も評価されます。 複合代入を使用して配列変数に+ =を適用すると(以下の配列を参照)、変数の値は設定解除されず(=が使用されている場合と同様)、新しい値は配列の最大インデックスより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"

または、式全体を(())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

関連情報