Вопрос по unix, ksh, shell, scripting – Диапазон переменных в KSH

10

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

#!/usr/bin/ksh

splitString() {

    string="[email protected];[email protected];[email protected]"

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

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

Попался !!!! Скрипт сейчас работает, проблем с ним нет. Совершил небольшую ошибку, вызвав функцию неправильно. Однако все равно хотелось бы понять область действия переменных в KSH Vivek

Ваш Ответ

2   ответа
2

Переменные обычно являются глобальными для оболочки, в которой они определены с момента их определения.

typeset команда может сделать их локальными для функции, в которой они определены, или, наоборот, сделать их автоматически экспортированными (даже если они обновлены).

Читайте "набрано" и & quot; целое число & quot; в man-странице или книге Корна.

Спасибо Эйб за совет. Я сделаю рецензию на странице руководства Vivek
16

Область действия переменной по умолчанию - весь сценарий.

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

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

В документации по ksh не указано,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"
@cdarke Вы правы, спасибо. Вы случайно не знаете ситуацию в ksh88? Я не могу воспроизвести поведение, которое Аскер описывает в ksh93.
Вы используете синтаксис функции POSIX. В ksh93, если вы используетеfunction splitSpring { ... } затем обзор сtypeset работает нормально, в противном случае набор текста игнорируется для целей определения объема.
ksh93 имеет только лексическую область видимости, а не динамическую. В основном все другие оболочки, связанные с ksh, используют динамическую область видимости, включая ksh88, bash и zsh. В ksh93 для работы с нелокальными переменными требуется либо использование глобальных переменных, либо передача переменных через nameref. Есть и статичные местные жители. Вы также можете изменить поведение функции, используя синтаксис определения функции POSIX, или вызывая функции в качестве аргументов для & quot; точки & quot; встроенный.
В ksh88 (и bash) область видимости работает одинаково для обоих стилей объявления функций. В ksh93 синтаксис функции POSIX имеет функциональность POSIx и ничего более, поэтому на трассировку функций также влияет.
@ Жиль Спасибо за подробное объяснение. Это очень помогло :) Vivek

Похожие вопросы