Przegląd skryptów w Windows PowerShell 2.0 (część 1)     Centrum skryptów - Systemy operacyjne

Przegląd skryptów w Windows PowerShell 2.0 (część 2)

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Przegląd skryptów w Windows PowerShell 2.0 (część 2)

(Uwaga: dzisiejszy artykuł z serii „Cześć, Skrypciarze" to przeredagowany fragment książki autorstwa Dona Jonesa i Jefferya Hicksa, która zostanie wkrótce wydana przez SAPIEN Press. Don wydał ponad 30 książek na tematy związane z IT. Publikuje też w czasopiśmie TechNet Magazine oraz w witrynach ScriptingAnswers.com i concentratedtech.com. Jeffery jest autorem lub współautorem kilku książek wydanych w serii SAPIEN TFM. Jest specjalistą MVP w zakresie Windows PowerShell, publikuje w witrynie Redmondmag.com i prowadzi stałą rubrykę w witrynie MCPMag.com. Więcej informacji o Jefferyu można uzyskać na stronie http://jdhitsolutions.com/blog (j.ang.). Dzięki, Don i Jeffery!)

----------

Podstawy pisania skryptów

Warto pamiętać, że wszystko, co omawiamy w związku ze skryptami, działa równie dobrze przy interaktywnym używaniu powłoki. Oznacza to, że możecie korzystać z opisywanych funkcji nawet, jeśli nie zamierzacie w ogóle pisać skryptów.

Zakres

Zanim zaczniemy pracę ze skryptami, należy wprowadzić pojęcie zwane zakresem, które jest bardzo ważne w Windows PowerShell. Jak dotąd pracowaliśmy zawsze z powłoką w sposób interaktywny. Oznacza to, że naszym zakresem był zakres globalny. Kiedy pracujemy w ten sposób, wszystko, co się dzieje, zachodzi w zakresie globalnym, więc właściwie jest tak, jakby zakresu w ogóle nie było.

Jednak uruchomienie skryptu powoduje, że Windows PowerShell tworzy nowy zakres skryptu, zawierający skrypt. Zakres skryptu jest jednostką podrzędną zakresu globalnego; jak z tego wynika, zakres globalny jest jednostką nadrzędną zakresu skryptu. Interakcja między tymi dwoma zakresami jest regulowana określonymi zasadami specjalnymi:

  • Zakres nadrzędny nie może „zajrzeć do środka" zakresu podrzędnego.
  • Zakres podrzędny z kolei może odczytywać elementy zakresu nadrzędnego, ale ich modyfikowanie wymaga użycia specjalnej składni.
  • Jeśli w zakresie podrzędnym zostanie podjęta próba zmodyfikowania elementu zakresu nadrzędnego bez użycia takiej składni, zostanie utworzony nowy element o takiej samej nazwie w obrębie zakresu podrzędnego. W takiej sytuacji zakres podrzędny praktycznie traci dostęp do elementu zakresu nadrzędnego o danej nazwie.

Elementy, o których mowa powyżej, to przede wszystkim zmienne i funkcje. Powtórzmy te zasady ze szczególnym uwzględnieniem zmiennych:

  • Zakres nadrzędny nie może uzyskać dostępu do zmiennych zdefiniowanych w zakresie podrzędnym.
  • Zakres podrzędny z kolei może odczytywać zmienne zdefiniowane w zakresie nadrzędnym, ale ich modyfikowanie wymaga użycia specjalnej składni.
  • Jeśli w zakresie podrzędnym zostanie podjęta próba zmodyfikowania zmiennej zakresu nadrzędnego bez użycia takiej składni, zostanie utworzony nowa zmienna o takiej samej nazwie w obrębie zakresu podrzędnego. W takiej sytuacji zakres podrzędny praktycznie traci dostęp do zmiennej zakresu nadrzędnego o danej nazwie.

Po utworzeniu funkcji -- bądź to przez zdefiniowanie jej w zakresie globalnym, bądź (co zdarza się częściej) w obrębie skryptu -- stanowi ona sama dla siebie lokalny zakres, będący zakresem podrzędnym zakresu, w którym została utworzona funkcja. Oto prosty przykład (wprawdzie nie omawialiśmy jeszcze funkcji, ale ta jest na tyle prosta, że powinna nadawać się do ilustracji):

         

1.  $var1 = "Dzień dobry"

2.  Function MyFunction {Write-Host $var1

3.   $var1 = "Do widzenia"

4.   Write-Host $var1

5.  }

6.  Write-Host $var1

7.  MyFunction

8.  Write-Host $var1

Uruchomienie tego skryptu pozwoliłoby uzyskać następujące dane wyjściowe:

           

Dzień dobry

Dzień dobry

Do widzenia

Dzień dobry

Dlaczego tak się dzieje? Pierwszym wykonywalnym wierszem tego skryptu jest jego wiersz początkowy, w którym ustawiana jest zmienna $var1 o wartości „Dzień dobry”. Następnie definiowana jest funkcja, która jednak nie jest jeszcze wykonywana. Windows PowerShell przeskakuje definicję funkcji i przechodzi do wiersza 7, który powoduje wyświetlenie zawartości zmiennej $var1 — jest to pierwszy wiersz danych wyjściowych. Następnie w wierszu 8 wywoływana jest funkcja MyFunction. Powoduje to wprowadzenie funkcji, stanowiącej zakres podrzędny zakresu skryptu. Wiersz 3 powoduje wyświetlenie zawartości zmiennej $var1. Ze względu na to, że w tym zakresie nie zdefiniowano zmiennej $var1, Windows PowerShell sprawdza, czy taka zmienna istnieje w zakresie nadrzędnym. Ponieważ taka zmienna istnieje, drugi wiersz danych wychodzących to również „Dzień dobry”. W wierszu 4 do zmiennej $var1 przypisywana jest nowa wartość. Zakres nie może bezpośrednio modyfikować zmiennych swojego zakresu nadrzędnego, ale wiersz 4 tworzy nową zmienną o nazwie $var1. Kiedy uruchamiany jest wiersz 5, zmienna $var1 istnieje już w zakresie lokalnym, więc trzecim wierszem danych wychodzących jest „Do widzenia”. Zamknięcie funkcji powoduje odrzucenie jej zakresu. Kiedy uruchamiany jest wiersz 9, zmienna $var1 nadal zawiera pierwotną wartość — funkcja nie modyfikowała tej zmiennej $var1. Tak więc ostatnim wierszem danych wychodzących jest ponownie „Dzień dobry”.

Spójrzmy teraz na ten skrypt w nieco zmodyfikowanej wersji:

1.  $var1 = "Dzień dobry"

2.  Function MyFunction {

3.   Write-Host $var1

4.   $script:var1 = "Do widzenia"

5.   Write-Host $var1

6.  }

7.  Write-Host $var1

8.  MyFunction

9.  Write-Host $var1

Zmodyfikowany wiersz 4 oznaczyliśmy pogrubieniem. Tym razem zobaczymy więc takie dane wyjściowe:

Dzień dobry

Dzień dobry

Do widzenia

Do widzenia

W obrębie tej funkcji użyliśmy wspomnianej wcześniej specjalnej składni, umożliwiającej zmodyfikowanie zmiennych jednostki nadrzędnej przez jednostkę podrzędną. Kiedy zaglądamy do zmiennej $var po raz pierwszy, jej wartość to „Dzień dobry”. Następnie wywołujemy funkcję, która odczytuje wartość zmiennej $var z zakresu nadrzędnego. Potem wprowadzamy zmianę, używając identyfikator zakresu. Windows PowerShell rozpoznaje cztery identyfikatory zakresu:

  • $global: umożliwia pracę z obiektami w zakresie globalnym.
  • $script: umożliwia pracę z obiektami w zakresie nadrzędnym skryptu.
  • $local: umożliwia pracę z obiektami w zakresie lokalnym.
  • $private: umożliwia pracę z obiektami w zakresie prywatnym.

Kiedy drugi raz odczytujemy zmienną $var, jej wartość to „Do widzenia”. Wykonanie skryptu powoduje zmianę zakresu nadrzędnego, a zmienna $var ma nadal wartość „Do widzenia”.

Istnieje jeszcze jedna technika, zwana dot sourcing, która pozwala wpływać na zakres. Jeszcze raz spójrzmy na nasz przykładowy skrypt z wprowadzonymi zmianami:

$var1 = "Dzień dobry"

Function MyFunction {

 Write-Host $var1

 $var1 = "Do widzenia"

$var2 = "Jestem tu od niedawna"Write-Host $var1

}

Write-Host $var1

Write-Host $var2

. MyFunction

Write-Host $var1

Jak widać, wywołujemy funkcję w przedostatnim wierszu kodu. Wprowadziliśmy kropkę, a następnie spację i nazwę funkcji. W ten sposób wymusiliśmy działanie funkcji nie we własnym zakresie, lecz w zakresie skryptu. Innymi słowy, uruchamiając coś — skrypt albo funkcję — przy użyciu techniki dot sourcing, instruujemy Windows PowerShell, by opuścić krok tworzenia nowego zakresu i uruchamiamy wszystkie polecenia w bieżącym zakresie.

Zmodyfikowany przykład powinien dać takie dane wyjściowe:

Dzień dobry

 

Dzień dobry

Do widzenia

Do widzenia

Jestem tu od niedawna

Pierwsze „Dzień dobry” to wartość zmiennej $var1 przed wywołaniem funkcji. Następnie skrypt podejmuje próbę wyświetlenia zmiennej $var2, która nie jest zdefiniowana. Funkcja z techniką dot sourcing powoduje ponowne wyświetlenie wartości zmiennej $var1. Wartość jest zmieniana na „Do widzenia” i wyświetlana ponownie. Wskutek działania funkcji wartość zmiennej $var1 została zmieniona, a ponieważ w funkcji tej zdefiniowano zmienną $var2, istnieje ona teraz w podstawowym zakresie skryptu.

Dot sourcing to przydatna sztuczka. Możemy np. napisać skrypt, który nie wykonuje żadnych działań oprócz zdefiniowania kilku funkcji narzędziowych, tzn. takich, które wykonują określone zadania, których będziemy czasami potrzebować (będzie to działać podobnie do apletów polecenia). Użycie techniki dot sourcing w celu umieszczenia tego skryptu w zakresie globalnym pozwoli nam zdefiniować te funkcje w zakresie globalnym. Dzięki temu będą dostępne tak samo, jak aplety polecenia albo zmienne globalne.

Zakres w Windows PowerShell to w rzeczywistości temat dużo bardziej złożony, niż przedstawiliśmy to tutaj. Chodziło jedynie o krótkie wprowadzenie tego pojęcia, gdyż będzie miało ono wpływ na większość skryptów.

 Do początku strony Do początku strony

Przegląd skryptów w Windows PowerShell 2.0 (część 1)     Centrum skryptów - Systemy operacyjne