변수는 언제 로컬이고 언제 전역인가요?

변수는 언제 로컬이고 언제 전역인가요?

다음 두 가지 기능을 고려하십시오.

f1() {
  if [ "$a" == "" ]; then
    a="0";
  else
    a=$(($a+1));
  fi;
  echo "$a";
}

f2() {
  echo "f1(): $($1)";
}

f1여러 번 호출 하면 a예상대로 증가합니다.

$ f1
0
$ f1
1
$ f1
2

하지만 내가 유적 f1에서 f2 a부르면 0:

$ f2 "f1"
f1(): 0
$ f2 "f1"
f1(): 0

함수에 선언된 변수가 전역 변수라는 말을 들었고 경험했습니다. 그렇다면 왜 그러한 차이가 있습니까? 이것은 특별한 경우입니까, 아니면 제가 올바른 방식으로 f1부르지 않는 것입니까?f2

f2좋아, 방금 정의가 다음과 같이 변경된 것을 확인했습니다 .

f2() {
  eval "$1";
}

문제는 해결되었지만 첫 번째 호출의 목적이 무엇인지 아는 것은 여전히 ​​흥미롭습니다 $($1). 정확히 어떤 역할을 하나요?

또한 f1.f2

f2() {
  ...
  res=$(eval "$1");
  ...
}

res통화할 때마다 동일합니다.f2 "f1"

왜?

답변1

f1에서 다음과 같이 정의된 경우 값은 a전역(bash)입니다 a.

local a

f1 정의를 다음으로 변경합니다.

f1() {
       local a
       if [ "$a" == "" ]; then
           a="0";
       else
           a=$(($a+1));
       fi;
           echo "$a";
     }

변수를 로컬로 만듭니다.

f2의 경우: 서브쉘 $(f2)에서 f2를 호출합니다. 하위 쉘 변수는 상위 쉘에 영향을 주지 않습니다.

답변2

subshell을 언급하는 모든 의견에 감사드립니다. 하지만 좀 더 자세한 답변을 드리고 싶습니다.

f1새 하위 쉘에서 호출될 때 마다 f2새 하위 쉘이 생성되고 3개의 명령만 실행됩니다.

    f1() {
1      if [ "$a" == "" ]; then
2        a="0";
      else
        a=$(($a+1));
      fi;
3      echo "$a";
    }

af1전역으로 만들고 하위 쉘에서 초기화했습니다( increment가 반복적으로 호출되므로 적어도 내 시스템에서는 a). 그러나 a생성된 다음 서브쉘에는 존재하지 않습니다.

관련 정보