Область переменных в KSH

Я написал пример функции KornShell, чтобы разделить строку, поместить ее в массив, а затем распечатать значения. Код, как показано ниже

#!/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 не распечатывает значения массива, поэтому я предполагаю, что это имеет какое-то отношение к области определенного массива.

Я новичок в скриптах оболочки, может ли кто-нибудь помочь мне понять область переменных в приведенном выше примере?

2 ответов


область по умолчанию переменной - это весь скрипт.

однако, когда вы объявляете переменную внутри функции, то переменная становится локальной для функции, которая заявляет он. КШ имеет динамическое определение области, поэтому переменная также доступна в функциях, вызываемых функцией, которая объявляет переменную. Это кратко задокументировано в раздел о функциях в руководстве. Обратите внимание, что в AT&T ksh (в отличие от pdksh и производные и аналогичные функции bash и zsh), это относится только к функциям, определенным с помощью function ключевое слово, а не функции, определенные с помощью традиционного f () { … } синтаксис. В AT&T ksh93 все переменные, объявленные в функциях, определенных с помощью традиционного синтаксиса, являются глобальными.

основным способом объявления переменной является typeset builtin. Он всегда делает переменную локальной (в AT&T ksh, только в функциях, объявленных с function). Если вы назначаете переменная, не объявив ее с typeset - Это глобальный.

документация КШ не указать set -A делает переменную локальной или глобальной, и разные версии делают это либо. В KSH 93u, pdksh или mksh переменная является глобальной, и ваш скрипт распечатывает значение. Кажется, у вас есть ksh88 или более старая версия ksh, где область является локальной. Я думаю, что инициализация str вне функции будет создана глобальная переменная, но я не конечно.

обратите внимание, что вы должны использовать локальную переменную, чтобы переопределить значение IFS: сохранение в другую переменную не только неуклюже, но и хрупко, потому что она не восстанавливает IFS правильно, если он был сброшен. Кроме того, вы должны выключить подстановка, потому что в противном случае, если строка содержит символы подстановки оболочки ?*\[ и одно из слов совпадает с одним или несколькими файлами в вашей системе, он будет расширен, например 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 команда может сделать их локальными для функции, в которой они определены, или, альтернативно, сделать их автоматически экспортированными (даже когда они обновляются.)

прочитайте "набор шрифтов" и "целое число" в manpage или книге Korn.