我认为typeset
是ksh
's local
,但这失败了,ksh93
尽管它适用于我所有其他typeset
支持的 shell(bash、yash、zsh、pdksh)
#!/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 ]
Run Code Online (Sandbox Code Playgroud)
是什么赋予了?
Sté*_*las 11
typeset
是 ksh93 的private
(使用像perl
's这样的静态范围my
,而不是local
动态范围)仅适用于使用 ksh 函数定义样式声明的函数:
function foo {
typeset var=whatever
...
}
Run Code Online (Sandbox Code Playgroud)
使用 Bourne 语法(或使用.
命令(顺便说一句,也可以用于 ksh 样式的函数)),没有范围(当然$1
,$2
...除外$#
)。因此,可以使用 Bourne 风格的函数来获取值或更改父上下文中变量的值或类型(尽管typeset -n
也可以与 ksh 风格一起使用)。
在 ksh88 中,typeset
正在使用 ksh 和 Bourne 函数定义样式进行动态范围界定。根据 David Korn 的说法,POSIX 没有指定 ksh 的变量范围,因为它是动态的(被认为是劣等的),这就是为什么他将其更改为静态范围ksh93
(完全重写)。
但与此同时,其他 shell 已经实现了变量范围,它们都使用动态范围来模拟 ksh88。
zsh
现在有一个private
关键字来具有类似于ksh93
's 的范围,除了local
/typeset
与动态范围类似 in ksh88
。
要查看静态范围和动态范围之间的区别,请比较:
"$shell" -c 'function f { typeset a=1; g; echo "$a"; }
function g { echo "$a"; a=2; }
a=0; f'
Run Code Online (Sandbox Code Playgroud)
其中带有$shell
==ksh93
输出:
0
1
Run Code Online (Sandbox Code Playgroud)
并带有ksh88
或bash
输出:
1
2
Run Code Online (Sandbox Code Playgroud)
zsh
:
$ zsh -c 'zmodload zsh/param/private
f() { private a=1; g; echo $a;}
g() { echo $a; a=2; }
a=0; f'
0
1
Run Code Online (Sandbox Code Playgroud)
为了能够在代码中使用本地范围移植到bash
,zsh
,ksh88
ksh93
,pdksh
,yash
或dash
/ FreeBSD
sh的,你可以这样做:
[ -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
Run Code Online (Sandbox Code Playgroud)
然后将您的函数声明为:
kshdef foo
shdef foo()
{
mylocal var
var=value
...
}
Run Code Online (Sandbox Code Playgroud)
在任何情况下,local
不同 shell 中的行为之间存在许多差异。除了上面提到的动态 vs 静态考虑之外,还有变量最初是否获得未设置或空值或从父作用域继承值。还有与readonly
,的交互unset
,无论local
/typeset
是关键字还是内置(影响 split+glob 处理)...
在 中使用 ksh 样式的函数定义还有其他含义,ksh93
有关详细信息,请参阅手册页。
归档时间: |
|
查看次数: |
1713 次 |
最近记录: |