Область переменных в 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.