TL; DR:对于简单的情形:开关函数定义的语法从f() compound-command
到function f { ...; }
。对于复杂的情况:依靠ksh93的只(更灵活),可以使用下面的荒谬黑客(硬),重写要严格POSIX符合(也许硬,不灵活),重写一个真正的语言(但壳很不错有时)。
没有“Linux ksh”。它在所有系统上表现相同,只取决于您使用的版本。
AIX发布了修改的ksh88。 ksh88有一个动态范围系统,类似于Bash和所有其他支持本地的shell,但与ksh93不同。为了让本地人在ksh93下工作,您必须使用“现代”语法,而不是POSIX语法来定义函数。这在ksh88中可能需要也可能不需要,因为它没有文档记录,也没有可能的方式供我测试,因为ksh88是专有软件,并且很可能甚至不能在现代x86硬件上运行。
如果上述内容是正确的,并且您的脚本是为ksh88编写的,那么只需切换函数定义语法就足以让本地变量至少起作用。然而,尽管ksh93的静态作用域远远优于其他shell的动态作用域,但确实造成了严重的可移植性问题 - 可能是所有shell脚本中最难解决的问题之一。
如果您需要便携式当地人,那么没有太棒的解决方案。我想出了两种技术,其“破发”的ksh范围更像ksh88 /庆典/ mksh/zsh,使用等
在非打破POSIX壳的首部作品。
#!/bin/sh
# (Partially) Working shells: dash, posh, bash, ksh93v, mksh, older zsh
# Broken shells: current zsh, busybox sh, non-bleeding edge alpha ksh93, heirloom
f() {
if ! ${_called_f+false}; then
# Your code using "x"
for x; do
printf '%s, ' "$x"
done
else
# This hackishly localizes x to some degree
_called_f= x= command eval typeset +x x 2\>/dev/null \; f '"[email protected]"'
fi
}
# demonstration code
x='outside f'; printf "$x, "; f 1 2 3; echo "$x"
第二种方法只适用于KSH般的炮弹和包括通过参考明确地传递一切,用间接广泛。
#!/usr/bin/env ksh
# bash, ksh93, mksh, zsh
# Breaking things for dash users is always a plus.
# This is crude. We're assuming "modern" shells only here.
${ZSH_VERSION+false} || emulate ksh
${BASH_VERSION+shopt -s lastpipe extglob}
unset -v is_{ksh93,mksh}
case ${!KSH_VERSION} in
.sh.version) is_ksh93= ;;
KSH_VERSION) is_mksh=
esac
function f {
# We want x to act like in dynamic scope shells. (not ksh93)
typeset x
g x
typeset -p x
}
function g {
# Note mksh and bash 4.3 namerefs kind of suck and are no better than eval.
# This makes a local of a pointer to the variable arg of the same name.
# Remember it's up to the programmer to ensure the sanity of any NAME
# passed through an argument.
${is_ksh93+eval typeset -n ${1}=\$1}
typeset y=yojo
# mksh... you fail at printf. We'll try our best anyway.
eval "$(printf %${is_mksh+.s%s=%s%.s }s=%q "$1" ${is_mksh+"${[email protected]}"} "$y")"
}
f
,如果你需要编写必须是便携式太强大的库代码为数不多的我只建议您考虑以下。
你好Ormaaj,非常感谢你的详细和非常有帮助的答案。似乎是我有错误的期望,还有更多的事情要做,比我希望的要多。但是现在我知道至少在移民过程中如何处理未来的问题。 – Cologne2202 2013-03-28 16:15:50