24.2를 읽은 후 . 지역 변수는 , 내가 변수 선언 생각 var
키워드가 local
의미하는 것을 var
의 값이 함수의 중괄호로 구분 코드 블록 내에서만 액세스 할 수있었습니다.
그러나 다음 예제를 실행 한 후, 나는 그가 발견 var
도 읽고, 액세스 코드의 블록에 의해 호출 기능에서 쓸 수 있습니다 – 즉,이 비록 var
선언 local
에 outerFunc
, innerFunc
여전히 그것을 읽고 그 값을 변경 할 수 있습니다.
#!/usr/bin/env bash
function innerFunc() {
var='new value'
echo "innerFunc: [var:${var}]"
}
function outerFunc() {
local var='initial value'
echo "outerFunc: before innerFunc: [var:${var}]"
innerFunc
echo "outerFunc: after innerFunc: [var:${var}]"
}
echo "global: before outerFunc: [var:${var}]"
outerFunc
echo "global: after outerFunc: [var:${var}]"
산출:
global: before outerFunc: [var:] # as expected, `var` is not accessible outside of `outerFunc`
outerFunc: before innerFunc: [var:initial value]
innerFunc: [var:new value] # `innerFunc` has access to `var` ??
outerFunc: after innerFunc: [var:new value] # the modification of `var` by `innerFunc` is visible to `outerFunc` ??
global: after outerFunc: [var:]
Q : 내 셸에 버그 (bash 4.3.42, Ubuntu 16.04, 64 비트)입니까, 아니면 정상적인 동작입니까?
편집 : 해결되었습니다. @MarkPlotnick이 지적했듯이 이것은 실제로 예상되는 동작입니다.
답변
쉘 변수에는 동적 범위가 있습니다. 변수가 함수의 로컬 변수로 선언되면 해당 범위는 함수가 반환 될 때까지 유지됩니다.
두 가지 예외가 있습니다.
-
ksh93에서 함수가 표준
function_name () { … }
구문으로 정의되면 로컬 변수는 동적 범위를 따릅니다. 그러나 함수가 ksh 구문으로 정의 된 경우function function_name { … }
로컬 변수는 어휘 / 정적 범위를 준수하므로이 함수는 다른 함수에서 볼 수 없습니다. -
zsh/private
에 autoloadable 플러그인zsh
으로 제공하는private
키워드 / 내장 정적 범위의 변수를 선언하는 데 사용될 수있다.
ash, bash, pdksh 및 파생 상품, bosh에는 동적 범위 만 있습니다.
답변
버그가 아닙니다. outerFunc 컨텍스트 내부의 호출은 해당 로컬 $ var 복사본을 사용합니다. outerFunc의 “local”은 전역이 변경되지 않았 음을 의미합니다. outerFunc 외부에서 innerFunc를 호출하면 글로벌 $ var가 변경되지만 outerFunc의 로컬 $ var은 변경되지 않습니다. innerFunc에 “local”을 추가하면 outerFunc의 $ var는 변경되지 않습니다. 본질적으로 3 개가 있습니다.
- $ global :: var
- $ outFunc :: var
- $ innerFunc :: var
Perl의 네임 스페이스 형식을 사용하려면
답변
함수를 사용하여 로컬 범위를 강제 할 수 있습니다.
sh_local() {
eval "$(set)" command eval '\"\$@\"'
}
예:
x() {
z='new value'
printf 'function x, z = [%s]\n' "$z"
}
y() {
z='initial value'
printf 'function y before x, z = [%s]\n' "$z"
sh_local x
printf 'function y after x, z = [%s]\n' "$z"
}
printf 'global before y, z = [%s]\n' "$z"
y
printf 'global after y, z = [%s]\n' "$z"
결과:
global before y, z = []
function y before x, z = [initial value]
function x, z = [new value]
function y after x, z = [initial value]
global after y, z = [initial value]
답변
에서 function innerFunc()
이 var='new value'
선언되지 않은 지역 , 그러므로 (함수가 호출 된 후) 눈에 보이는 범위에서 사용할 수 있습니다.
에 반대로, function outerFunc()
가 local var='initial value'
선언 된 지역 , 그러므로 (함수가 호출 된 경우에도) 전역에서 사용할 수 없습니다.
innerFunc()
의 하위 항목으로 호출 되었으므로 outerFunc()
var의 로컬 범위 내에 outerFunc()
있습니다.
man 1 bash
명확히하는 데 도움이 될 수 있습니다
로컬 [옵션] [이름 [= 값] …]
각 인수에 대해 name이라는 로컬 변수가 작성되고 값이 지정됩니다. 옵션은 선언에 의해 허용되는 옵션 중 하나 일 수 있습니다. 함수 내에서 local을 사용하면 변수 이름에 해당 함수와 해당 하위로 제한된 가시적 범위가 있습니다. …
설명에서 예상되는 암시적인 동작은에서 선언 local var='new value
하여 얻을 수 있습니다 function innerFunc()
.
다른 사람들이 말했듯이, 이것은 bash 쉘의 버그가 아닙니다. 모든 것이 제대로 작동합니다.