KSH中的变量范围

Viv*_*vek 10 unix shell scripting ksh

我编写了一个示例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]}";
Run Code Online (Sandbox Code Playgroud)

现在echo不打印出数组的值,所以我假设它与定义的数组的范围有关.

我是Shell脚本的新手,有人可以帮助我理解上面例子中的变量范围吗?

Gil*_*il' 17

变量的默认范围是整个脚本.

但是,当您在函数内声明变量时,该变量将变为声明它的函数的本地变量.Ksh具有动态范围,因此该变量也可以在声明变量的函数调用的函数中访问.本手册中的功能部分简要介绍了这一点.请注意,在AT&T ksh中(与pdksh和派生类相反,以及bash和zsh的类似功能),这仅适用于使用function关键字定义的函数,而不适用于使用传统f () { … }语法定义的函数.在AT&T ksh93中,在使用传统语法定义的函数中声明的所有变量都是全局变量.

声明变量的主要方法是使用typeset 内置函数.它总是使变量本地(在AT&T ksh中,仅在声明的函数中function).如果在未声明变量的情况下分配给变量typeset,则它是全局变量.

ksh文档没有指定是set -A将变量设置为局部变量还是全局变量,并且不同的版本也可以.在ksh 93u,pdksh或mksh下,变量是全局的,您的脚本会打印出值.您似乎拥有ksh88或旧版本的ksh,其范围是本地的.我认为在函数str外部初始化会创建一个全局变量,但我不确定.

请注意,您应该使用局部变量来覆盖以下值IFS:保存到另一个变量不仅笨拙,而且还很脆弱,因为IFS如果未设置它则无法正确恢复.此外,你应该关闭通配符,否则如果字符串包含shell的通配符?*\[和一个关键词恰好符合您系统上的一个或多个文件时,它会扩大,比如set -A $string这里stringa;*将导致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"
Run Code Online (Sandbox Code Playgroud)