2017-08-28 13 views
1

私はforループを書いています。しかし、ループは位置引数の内容に依存します。bash:2つの異なるループの分岐の場合

  • 位置引数がseq 2 1 10ある場合、ループは位置引数は、1 2 5 7 10として純粋に数値である場合、ループはfor i in 1 2 5 7 10あるfor i in $(seq 2 1 10)

  • あります。

私はこれを試してみましたが、それはうまくいきませんでした:

test() { 
if [[ $1 == seq ]] 
then 
for i in $(seq $2 $3 $4) 
else 
for i in [email protected] 
fi 
do 
echo $i 
done 
} 

私もこれを試してみました:

test2() { 
if [[ $1 == seq ]] 
then 
sss="for i in $(seq $2 $3 $4)" 
else 
sss="for i in [email protected]" 
fi 
$sss 
do 
echo $i 
done 
} 

も動作しません。

は、だから私の質問は以下のとおりです。

  1. 私は内部の場合は、明示的な2つのループを書くことができます知っています。しかし、ループの内容が大きい場合、これはコードスペースの無駄です。もっと良い方法はありますか?
  2. 私の2番目の試みでは、なぜ$sssfor文に展開され、bashによって適切に解析されないのですか?
+0

'test'はシェル組み込みの' test'と衝突するので、関数のための最良の名前ではありません。 – codeforester

答えて

1

数値リストを配列に保存します。 $sssfor文に展開されていないとのbashで適切に解析されますなぜ私の第二の試みでは、

test() { 
    if [[ $1 == seq ]] 
    then 
     numbers=($(seq "$2" "$3" "$4")) 
    else 
     numbers=("[email protected]") 
    fi 

    for i in "${numbers[@]}" 
    do 
     echo $i 
    done 
} 

変数は、実行するコマンドに展開が、フロー制御にforループまたはif文のよう構築することができません。それらは直接書き出す必要があり、変数に格納することはできません。試してみると、bashはforというコマンドを実行しようとします。つまり、forという名前のバイナリは/bin/usr/binなどです。 for i in "[email protected]"と等価である

test() 
{ 
    if [[ $1 == seq ]]; then 
     set -- $(seq $2 $3 $4) 
    fi 
    for i; do 
     echo $i 
    done 
} 

for iこと:

1

John Kugelmanの答えのように配列を使用する代わりに、位置パラメータを変更するset --を使用することです。

ジョンはすでにそれがうまくいかなかった理由について言及しました。制御フローが解析された後、変数補間と分割が発生します。

+0

'set --'について紹介してくれてありがとう – user15964

関連する問題