シェルは再帰をサポートしますか?

シェルは再帰をサポートしますか?

シェルスクリプトで再帰関数を作成しようとしています。次のコードを考えてみましょう。

function printA {
    if [[ "$1" = 0 ]]; then
        return
    else
        echo "a$(printA $(("$1" - 1)))"
    fi
}

printA 10

function factorial {

    if [[ "$1" = 0 ]]; then
        return 1
    else
        return $(( "$1" * $(factorial $(( $1 - 1 )) ) ))
    fi
}

echo $(factorial 5)    

コードが失敗します。

  • bash(3.0)

recur.sh:行5:「10」 - 1:構文エラー:オペランドが必要です(エラーは「10」 - 1で示されています)

recur.sh: 行 16: "1" * : 構文エラー: オペランドが必要です (エラーは ""1" * " で示される)。

recur.sh:行16:「2」*:構文エラー:オペランドが必要です(エラーは「2」*」と表示されます)。

recur.sh: 行 16: "3"*: 構文エラー: オペランドが必要 (エラーは ""3"*" で示される)

recur.sh:行16:「4」*:構文エラー:オペランドが必要です(エラーは「4」*」と表示されます)。

recur.sh:行16:「5」*:構文エラー:オペランドが必要です(エラーは「5」*」と表示されます)。

  • zsh(4.2.1)

printA:1: 無効な数学表現: 無効な文字: "

ファクトリアル: 5: 無効な数学表現: 無効な文字: "

しかし、部分的に正常に使用されましたksh88。 2番目の機能だけが失敗しました。

あああああああああ

recur.sh[5]: 1 * : より多くのトークンが予想されます。

recur.sh[5]: 2 * : より多くのトークンが予想されます。

recur.sh[5]: 3 * : より多くのトークンが予想されます。

recur.sh[5]: 4 * : より多くのトークンが予想されます。

recur.sh[5]: 5 * : より多くのトークンが予想されます。

  • 私は何が間違っていましたか?
  • bashとzshは別の再帰構文をサポートしていますか?
  • なぜ2番目の関数(factorial)が失敗するのですkshか?

ポリスチレン:知っています。再帰は悪く、パフォーマンスも悪いです。代わりに通常のループを使用する必要があります。 bla bla bla.再帰が良いか悪いかを議論するのではなく、通常のシェルがそれをサポートしているかどうかを議論することです。私は単純な反復ループがトリックを実行するときに本番で再帰関数を送信するほど愚かではありません。 :)

ベストアンサー1

  • 構文エラー:算術演算には引用符は使用されません。
  • 論理エラー:STDOUTと値を混合していますreturn

値をSTDOUTに渡します。

function factorial {
    (( $1 )) &&
    echo $(( $1 * $( factorial $(( $1 - 1 )) ) )) ||
    echo 1
}

factorial 5

またはreturn彼らは:

function factorial {
    (( $1 )) || return 1
    factorial $(( $1 - 1 ))
    return $(( $1 * $? ))
}

factorial 5
echo $?

どちらのコードもbashksh(もちろん93、88についてはわかりません)、で動作しますzsh。したがって、シェルは再帰をサポートします。

おすすめ記事