我已经写了一个示例KornShell函数来分割一个string,把它放在一个数组,然后打印出来的值。 代码如下
#!/usr/bin/ksh splitString() { string="abc@hotmail.com;xyz@gmail.com;uvw@yahoo.com" oIFS="$IFS"; IFS=';' set -A str $string IFS="$oIFS" } splitString echo "strings count = ${#str[@]}" echo "first : ${str[0]}"; echo "second: ${str[1]}"; echo "third : ${str[2]}";
现在echo
不打印出数组的值,所以我认为它与定义的数组范围有关。
我是壳牌脚本的新手,有没有人能帮我理解上面例子中variables的范围?
变量的默认范围是整个脚本。
但是,当你在一个函数中声明一个变量时,该变量变成声明它的函数的本地。 Ksh具有动态范围 ,因此变量也可以在由声明该变量的函数调用的函数中访问。 这在手册中有关功能的章节中有详细记录 。 请注意,在AT&T ksh中(与pdksh和派生类型以及bash和zsh的相似特征相对),这仅适用于使用function
关键字定义的function
,而不适用于使用传统f () { … }
语法定义的function
。 在AT&T ksh93中,用传统语法定义的函数中声明的所有变量都是全局变量。
声明一个变量的主要方法是使用内置的typeset
。 它总是使本地变量(在AT&T ksh中,只在函数声明的function
)。 如果您将一个变量赋值给一个变量而没有用typeset
声明它,那么这个变量是全局的。
ksh文档没有指定set -A
是使本地变量还是全局变量,而不同的版本使其成为可能。 在ksh 93u,pdksh或mksh下,变量是全局的,你的脚本确实打印出这个值。 您看起来有ksh88或ksh的旧版本,其中作用域是本地的。 我认为在函数外初始化str
会创建一个全局变量,但我不确定。
请注意,您应该使用本地变量来覆盖IFS
的值:保存到另一个变量不仅笨拙,而且易碎,因为如果未设置,它将不会正确还原IFS
。 此外,你应该关闭globbing,否则如果字符串包含shell globbing字符?*\[
和其中一个单词碰巧匹配您的系统上的一个或多个文件将扩大,例如set -A $string
,其中string
是a;*
将导致包含当前目录中文件名列表的str
。
set -A str function splitString { typeset IFS=';' globbing=1 case $- in *f*) globbing=;; esac set -f set -A str $string if [ -n "$globbing" ]; then set +f; fi } splitString "$string"
变量通常是全局的,它们是从定义的时候定义的。
typeset
命令可以使它们在其定义的函数中是本地的,或者可以使它们自动导出(即使它们被更新)。
在手册页或Korn的书中阅读“typeset”和“integer”。