シェルのforループの制御変数の範囲は何ですか? [閉鎖]

シェルのforループの制御変数の範囲は何ですか? [閉鎖]

シェルのforループについて質問があります。

次の簡単なシェルスクリプトを考えてみましょう。

#!/bin/sh
loop() {                                                                                                                                                                                                                                                                                                               
    for i in 1 2 3 4; do                                                                                                                                           
        if [ $i -eq 2 ]; then                                                                                                                                      
            [ $1 -eq 2 ] && return 1                                                                                                                           
            loop $(($1 + 1)) && return 1                                                                                                                     
        fi                                                                                                                                                         
    done                                                                                                                                                           
return 1                                                                                                                                                       
}                                                                                                                                                                  

loop 0       

パラメータ(および関数パラメータ)を除くすべての変数はグローバル変数です。したがって、関数にローカル変数が必要な場合は、それをパラメータとして渡す必要があります。

この単純なスクリプトを実行してみましたが、forループリスト(この場合は1 2 3 4)もローカルであるかどうかはわかりません。以下を参照してください。

+ loop 0
+ for i in 1 2 3 4
+ '[' 1 -eq 2 ']'
+ for i in 1 2 3 4
+ '[' 2 -eq 2 ']'
+ '[' 0 -eq 2 ']'
+ loop 1
+ for i in 1 2 3 4
+ '[' 1 -eq 2 ']'
+ for i in 1 2 3 4
+ '[' 2 -eq 2 ']'
+ '[' 1 -eq 2 ']'
+ loop 2
+ for i in 1 2 3 4
+ '[' 1 -eq 2 ']'
+ for i in 1 2 3 4
+ '[' 2 -eq 2 ']'
+ '[' 2 -eq 2 ']'
+ return 1
+ for i in 1 2 3 4
+ '[' 3 -eq 2 ']'
+ for i in 1 2 3 4
+ '[' 4 -eq 2 ']'   <- here is $i == 4
+ return 1
+ for i in 1 2 3 4
+ '[' 3 -eq 2 ']'   <- here is $i == 3, correctly behaving as local variable ...
+ for i in 1 2 3 4
+ '[' 4 -eq 2 ']'
+ return 1

forループが内部的にどのように機能するかを教えてくれる人はいますか? forループリストについては少し混乱しています。これは「ローカル変数」のように動作します。

すべての答えに心から感謝します! :)

答え1

$ reset() { i=$1; }
$ for i in 1 2 3 4 ; do echo -n "$i "; reset 3; echo "$i" ; done;
1 3
2 3
3 3
4 3

ilocal内部では行われないので、対応するreset変更は関数の外部で見ることができます。ただし、変更は後続の反復で得られる値には影響しませんi。コマンドiにリストされている単語は、期待forどおりに一度に1つずつ順番に割り当てられます。i

はい。単語リストの位置を知らせる「隠されたポインタ」があります。そこにあるはずです。それ以外の場合、likeなどの繰り返し単語を含むループはfor i in a a a ; do ...機能しません。繰り返すたびにi同じ値が得られますが、ループはまだ一定の繰り返し回数だけ実行されます。

答え2

何をしたいのか分かりませんが、

  1. return 0あなたは関数から決して("true")、だからそれはいいえすべての組み合わせが試行されるまで戻ります。
  2. $iはいいいえローカル変数:

    $ foo() { i=1; bar; }
    $ bar() { echo $i; }
    $ foo
    1
    
  3. 各コマンドがどの行にあるかを確認してデバッグできます。

    trap 'printf "$LINENO "' DEBUG
    
  4. $1それぞれの地域関数呼び出し、関数が自分自身を呼び出しても継続されません。

    $ foo() { if [ $# -ne 0 ]; then echo "One more time"; foo; fi; }
    $ foo 1
    One more time
    

    これはすべての主要な高度なプログラミング言語に当てはまります。それ以外の場合、再帰は完全に壊れます。

関連情報