나는 typeset
그것이 실패 ksh
한다고 생각했지만 다른 모든 지원 쉘(bash, yash, zsh, pdksh) 에서는 작동하지만 local
이것은 실패합니다.ksh93
typeset
#!/bin/ksh -ex
foo(){
typeset a b
a=0; b=1
return
}
a=a; b=b
foo
#confirm that the globals didn't change
[ "$a" = a ]
[ "$b" = b ]
무엇을 제공합니까?
답변1
typeset
ksh93용입니다( private
동적 범위 지정 대신 s와 같은 정적 범위 지정 사용). ksh 함수 정의 스타일을 사용하여 선언된 함수에만 작동합니다.perl
my
local
function foo {
typeset var=whatever
...
}
Bourne 구문을 사용하면(또는 .
ksh 스타일 함수에서도 작동하는 명령을 사용하면) 범위가 없습니다(물론 , $1
... $2
제외 $#
). 따라서 Bourne 스타일 함수를 사용하여 상위 컨텍스트에서 값을 가져오거나 변수의 값 또는 유형을 변경할 수 있습니다( typeset -n
ksh 스타일에서도 사용할 수 있음).
ksh88에서는 typeset
동적 범위 지정을 위해 ksh 및 Bourne 함수 정의 스타일을 사용합니다. David Korn에 따르면 POSIX는 ksh에 대한 변수 범위를 지정하지 않습니다.동적(열등한 것으로 간주) 그래서 그는 정적 범위 ksh93
(완전 재작성)로 변경했습니다.
그러나 동시에 다른 쉘도 변수 범위 지정을 구현했으며 모두 사용했습니다.동적범위는 ksh88을 모방합니다.
zsh
이제 in 과 유사한 동적 범위를 갖는 / 외에도 private
s 와 유사한 범위를 갖는 키워드가 있습니다.ksh93
local
typeset
ksh88
정적 범위와 동적 범위의 차이점을 보려면 다음을 비교하십시오.
"$shell" -c 'function f { typeset a=1; g; echo "$a"; }
function g { echo "$a"; a=2; }
a=0; f'
여기서 $shell
== ksh93
출력:
0
1
그리고 다음을 사용하거나 ksh88
출력 bash
합니다.
1
2
zsh
:
$ zsh -c 'zmodload zsh/param/private
f() { private a=1; g; echo $a;}
g() { echo $a; a=2; }
a=0; f'
0
1
bash
, zsh
, ksh88
ksh93
또는 pdksh
/sh 로 이식 가능한 yash
코드에서 로컬 범위를 사용 하려면 다음을 수행할 수 있습니다.dash
FreeBSD
[ -n "$BASH_VERSION" ] && shopt -s expand_aliases
alias shdef= kshdef='#'
if type typeset > /dev/null 2>&1; then
alias mylocal=typeset
if (a=1; f() { typeset a=2; }; f; [ "$a" = 2 ]); then
alias shdef='#' kshdef='function'
fi
else
alias mylocal=local
fi
그런 다음 함수를 다음과 같이 선언하십시오.
kshdef foo
shdef foo()
{
mylocal var
var=value
...
}
그럼에도 불구하고 local
서로 다른 쉘의 동작에는 많은 차이가 있습니다. 위에서 언급한 동적 및 정적 고려 사항 외에도 변수가 처음에 설정되지 않은 값 또는 null 값을 가져오는지 또는 상위 범위에서 해당 값을 상속하는지 여부도 있습니다. / 가 키워드 인지 내장인지(split+glob 처리에 영향을 미침) 와의 readonly
상호 작용 도 있습니다 ...unset
local
typeset
ksh 스타일 함수 정의 사용에는 다른 의미가 있습니다 ksh93
. 자세한 내용은 매뉴얼 페이지를 참조하세요.
더 읽어보기
- http://austingroupbugs.net/view.php?id=767표준화를 위해 POSIX를 추천합니다
sh
. - 쉘 목록은 지역 변수를 정의하기 위해 `local` 키워드를 지원합니다.