2012-08-17 15 views
10

Napisałem próbkę funkcji KornShell, aby podzielić ciąg, umieścić go w tablicy, a następnie wydrukować wartości. Kod jest jak poniżejZakres zmiennych w KSH

#!/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]}"; 

Teraz echo nie wydrukować wartości tablicy, więc zakładam, że ma coś wspólnego z zakresem określonym w tablicy.

Jestem nowy w Skrypty Shell, czy ktoś może mi pomóc ze zrozumieniem zakresu zmiennych w powyższym przykładzie?

+0

Gotcha !!!! Skrypt działa, bez problemów. Zrobiłem niewielki błąd wywoływania funkcji w niewłaściwy sposób. Jednak nadal chciałbym zrozumieć zakres zmiennych w KSH – Vivek

Odpowiedz

16

Domyślnym zakresem zmiennej jest cały skrypt.

Jednak po zadeklarowaniu zmiennej wewnątrz funkcji zmienna staje się lokalna dla funkcji, która ją deklaruje. Ksh ma dynamic scoping, więc zmienna jest również dostępna w funkcjach wywoływanych przez funkcję deklarującą zmienną. Jest to ostro udokumentowane w section on functions in the manual. Zauważ, że w AT & T ksh (w przeciwieństwie do pdksh i pochodnych oraz podobnych cech basha i zsh), dotyczy to tylko funkcji zdefiniowanych słowem kluczowym function, a nie funkcjami zdefiniowanymi tradycyjną składnią f() { … }. W AT & T ksh93 wszystkie zmienne zadeklarowane w funkcjach zdefiniowanych tradycyjną składnią są globalne.

Głównym sposobem deklarowania zmiennej jest typesetbuiltin. Zawsze tworzy zmienną lokalną (w AT & T ksh, tylko w funkcjach zadeklarowanych przy function). Jeśli przypiszesz zmiennej bez zadeklarowania jej z typeset, jest to globalne.

Dokumentacja ksh nie określa, czy set -A tworzy zmienną lokalną czy globalną, i czynią to również różne wersje. Pod ksh 93u, pdksh lub mksh zmienna jest globalna, a skrypt wypisuje wartość. Wygląda na to, że masz ksh88 lub starszą wersję ksh, gdzie zasięg jest lokalny. Myślę, że inicjowanie poza funkcją utworzyłoby zmienną globalną, ale nie jestem pewien.

Pamiętaj, że powinieneś użyć zmiennej lokalnej, aby przesłonić wartość IFS: zapisanie do innej zmiennej jest nie tylko niezdarne, ale także kruche, ponieważ nie przywraca prawidłowo wartości IFS, jeśli była wyłączona. Ponadto należy wyłączyć globowanie, ponieważ w przeciwnym razie, jeśli ciąg znaków zawiera znaki globujące powłoki ?*\[, a jedno ze słów pasuje do jednego lub więcej plików w systemie, zostanie ono rozwinięte, np. set -A $string gdzie string jest a;* spowoduje wyświetlenie str zawierającego listę nazw plików w bieżącym katalogu.

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" 
+0

Używasz składni funkcji POSIX. W ksh93, jeśli użyjesz 'function splitSpring {...}', to ustalenie zakresu z 'typeset' działa dobrze, w przeciwnym razie zestaw będzie ignorowany do celów scopingu. – cdarke

+0

@cdarke Masz rację, dzięki. Czy zdajesz sobie sprawę z sytuacji w ksh88? Nie mogę odtworzyć zachowania, które pytający opisuje w ksh93. – Gilles

+0

W ksh88 (i bash) scoping działa tak samo dla obu stylów deklaracji funkcji. W ksh93 składnia funkcji POSIX ma funkcjonalność POSIx i nic więcej, więc wpływa to również na śledzenie funkcji. – cdarke

2

Zmienne są zwykle globalne względem powłoki, w której są zdefiniowane od momentu zdefiniowania.

Komenda typeset może sprawić, że lokalne dla funkcji zostały zdefiniowane w, lub alternatywnie, aby je automatycznie eksportowane (nawet gdy są one aktualizowane.)

Czytaj up „przygotowana” i „całkowitą” w strona podręcznika lub książka Korn.

+0

Dzięki Abe za cynk.Zrobię odczyt na stronie man. – Vivek