83728


# 質問事項

bashで用いる変数の中身が数値でもコマンドの文字列でも同じ記述で値を算出する方法がありますでしょうか？

# 実際の問題

bashで竹内関数を実装しようと試み、以下のように書いてみました。  
実行環境はUbuntu 18.04です。

[code]

    tarai(){
        if [[ "$1" =~ tarai.* ]]; then
            arg1=`$1`
        else
            arg1=$1
        fi
        if [[ "$2" =~ tarai.* ]]; then
            arg2=`$2`
        else
            arg2=$2
        fi
        if ((arg1 > arg2)); then
            tarai "tarai $(($1-1)) $2 $3" "tarai $(($2-1)) $3 $1" "tarai $(($3-1)) $1 $2"
        else
            echo $((arg2))
        fi
    }
    
    tarai $1 $2 $3
    
[/code]

ここで`tarai`関数内の`$1`と`$2`には普通の整数値と`tarai 10 5
0`のような文字列の両方が入るので上記のif文を入れていますが、なんとかこのif文無しに記述することはできないものでしょうか？  
自分の知識レベルとしては業務上ファイル操作等で困らない程度にbashを知っている状態にちょっと算術式を学んだくらいになります。  
以上、よろしくお願いします。


CC BY-SA 4.0
2021-11-19T12:10:05.820
83720
2021-11-20T08:15:29.063
41978
question
ubuntu bash
bashでコマンド実行と値を同列に扱う方法があるか


**tarai.sh**

[code]

    #!/bin/bash
    
    PATH=
    
    tarai(){
        arg1=$($1 2>/dev/null || printf $1)
        arg2=$($2 2>/dev/null || printf $2)
    
        if ((arg1 > arg2)); then
            tarai "tarai $(($1-1)) $2 $3" "tarai $(($2-1)) $3 $1" "tarai $(($3-1)) $1 $2"
        else
            echo $((arg2))
        fi
    }
    
    tarai $*
    
[/code]

**実行結果**

[code]

    bash$ time ./tarai.sh 10 5 0
    10
    
    real    0m0.108s
    user    0m0.106s
    sys     0m0.015s
    
    bash$ time ./tarai.sh 50 30 0
    50
    
    real    0m3.409s
    user    0m3.133s
    sys     0m0.593s
    
[/code]


CC BY-SA 4.0
2021-11-19T14:09:38.407
83722
2021-11-19T14:49:34.677
2021-11-19T14:49:34.677
47127
47127
83720
answer


次の方法はいかがでしょうか。

[code]

    #!/bin/bash
    tarai(){
        eval arg1="$1"
        eval arg2="$2"
        if ((arg1 > arg2)); then
            tarai '"$(tarai $(('"$1"'-1)) '"$2"' '"$3"')"'   '"$(tarai $(('"$2"'-1)) '"$3"' '"$1"')"'   '"$(tarai $(('"$3"'-1)) '"$1"' '"$2"')"'
        else
            echo $((arg2))
        fi
    }
    
    tarai $1 $2 $3
    
[/code]

tarai で始まる式の代入を

[code]

    arg1=`$1`
    
[/code]

ではなく数値の代入に合わせて

[code]

    arg1=$1
    
[/code]

の形式にしてみました。  
コマンド置換の記述を呼び出し側の実引数に記述して、taraiの中でevalを使って評価しています。

* * *

なお、質問された方のコードでは以下のケースでエラーになります。

[code]

    tarai 2 1 0
    
[/code]

[code]

    ./tarai.sh: 行 14: tarai 1 1 0-1: 式に構文エラーがあります (エラーのあるトークンは "1 1 0-1")
    
[/code]

呼び出し側で評価したい引数とtataiの中で評価すべき引数を見直すことによりエラーは解消します。回答のコードは修正済みです。


CC BY-SA 4.0
2021-11-20T06:22:59.953
83728
2021-11-20T08:15:29.063
2021-11-20T08:15:29.063
35558
35558
83720
answer