構文エラー:オペランドが必要です(「/」とマークされたエラー)。

構文エラー:オペランドが必要です(「/」とマークされたエラー)。

次のbashスクリプトがあります

# 1 + x^2/2! + x^4/4! + ... + x^(2n)/(2*n)!
#!/bin/bash
factorial() {
    n=$1
    fact=1
    for ((i = 2; i <= $n; i++)); do
        fact=$(expr $fact \* $i)
    done
    return $fact
}

read -p "x = " x
read -p "n = " n

sum=0
for ((i = 1; i <= n; i++)); do
    val=$((2 ** ($i - 1)))
    ex=$(($x ** $val))
    f=$(factorial $val)
    a=$(($ex / $f))
    sum=$(($sum + $a))
done
echo $sum

上記のシリーズを実装しようとしています。解決策は必要ありません。なぜエラーが発生するのかわかりません。

間違い:

x = 1
n = 2
sum_of_series.sh: line 20: 1 / : syntax error: operand expected (error token is "/ ")

答え1

a=$(($ex / $f))(除算)演算子の後にオペランドがないため、エラーメッセージが行のために発生します。/したがって、変数fが空の文字列であるかどうかはすぐに疑われます。

その理由は、$( )割り当て時のコマンド置換動作によるものです。fこれは、閉じたコマンドパイプラインを実行したときにstdoutの内容を収集します。関数factorial()が標準出力に何も書き込まないため、fに割り当てられた値は空です。解決策は、代わりに値をエコーまたは印刷することですreturn(例:)printf '%s\n' "${fact}"

役に立つかもしれない追加の注意事項:

returnステートメントの値は、関数が生成できるデータではなく、関数の状態を表します。 returnステートメントがない場合、関数で実行された最後のコマンドの終了ステータスが呼び出し元に戻されます。

戻り状態は8ビットに切り捨てられ、符号がないため、0〜255の範囲のみ使用できます。

また、外部コマンドの状態に関する追加の規則もあります。シグナルによって終了されたプロセスの状態は128 +シグナル番号です。シェルが新しいプロセスを作成したり、コマンドを実行できなかった場合は、126または127を返すことができます。状態0は通常成功を示し、1から始まる小さな整数は、コマンドによって検出されたエラーまたは異常な結果を示します。シェル関数でも同じ規則に従い、絶対にこのようにデータ値を返さないのが賢明だと思います。

シェル操作(GNU / bashマニュアルに従う)は、固定幅整数の計算を実行します。私のシステムでは、この値は64ビット符号付き整数に見えますが、システムとディストリビューションによって異なる場合があります。 31 ビットは 12! のみ保存でき、63 ビットは 20! のみ保存できるため、範囲が制限される場合があります。

このスニペットは、Bash算術が約9.22e+18から63ビットをオーバーフローすることを示しています。

Paul--) for k in {1..10}; do
> printf '%s %s\n' $k $(( 3000000000000000000 * k ))
> done
1 3000000000000000000
2 6000000000000000000
3 9000000000000000000
4 -6446744073709551616
5 -3446744073709551616
6 -446744073709551616
7 2553255926290448384
8 5553255926290448384
9 8553255926290448384
10 -6893488147419103232
Paul--) 

大きな数値の場合、最初の選択は数値のサイズを無制限に受け入れますが、逆ポーランド表記法(RPN)を必要とするdcコマンドです。このフラグメントは、最大10個の継承をリストするRPNコマンドを生成します!

Paul--) { echo 1; seq -s ' p * p ' 2 10; echo ' p * p q'; }
1
2 p * p 3 p * p 4 p * p 5 p * p 6 p * p 7 p * p 8 p * p 9 p * p 10
 p * p q
Paul--) 

実行内容は次のとおりです(ただし、最大400個までテストしました!)。

Paul--) { echo 1; seq -s ' p * p ' 2 10; echo ' p * p q'; } | dc
2
2
3
6
4
24
5
120
6
720
7
5040
8
40320
9
362880
10
3628800
Paul--) 

関連情報