ksh93 中的排版無法按預期工作
我以為
typeset
是ksh
’slocal
,但這失敗了,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 ]
是什麼賦予了?
typeset
是 ksh93private
(使用像perl
‘s這樣的靜態作用域my
,而不是local
動態作用域)僅適用於使用 ksh 函式定義樣式聲明的函式:function foo { typeset var=whatever ... }
使用 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
具有動態作用域,如 inksh88
。要查看靜態和動態範圍之間的區別,請比較:
"$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
、或/ sh 的程式碼中使用本地範圍pdksh
,您可以執行以下操作: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
在任何情況下,不同 shell 中的行為之間存在許多差異。除了上面提到的動態與靜態考慮之外,變數最初是否獲得未設置或空值或從父範圍繼承值。還有與 , 的互動readonly
,unset
無論local
/typeset
是關鍵字還是內置(影響 split+glob 處理)…在 中使用 ksh 樣式的函式定義還有其他含義
ksh93
,請參閱手冊頁了解詳細資訊。更多閱讀