Как Scopes влияят върху скриптовете на PowerShell
В пакетните скриптове промените в променливите на обкръжение имат глобално въздействие върху текущата сесия по подразбиране. За PowerShell, точно обратното е вярно, защото обхватите се използват за изолиране на модификациите на скрипта. Тук ще разгледаме как областите засягат скриптовете на PowerShell и как да работят в и около тях.
Какво е обхват?
В PowerShell "обхват" се отнася до текущата среда, в която работи скрипт или командна обвивка. Обхватът се използва за защита на определени обекти в околната среда от неволно модифициране от скриптове или функции. По-специално, следните неща са защитени от модификация от команди, изпълнявани от друго поле, освен ако не е посочено друго от параметрите в тези команди:
- Променливи
- Псевдоними
- Функции
- Задвижвания PowerShell (PSDrives)
Нови обхвати се създават всеки път, когато стартирате скрипт или функция, или когато създавате нова сесия или копие на PowerShell. Обхватите, създадени чрез стартиране на скриптове и функции, имат връзка "родител / дете" с обхвата, от който са създадени. Има няколко области, които имат особено специално значение и могат да бъдат достъпни по име:
- Най- в световен мащаб обхватът е обхватът, който се създава, когато се стартира PowerShell. Тя включва променливите, псевдонимите, функциите и PSDrives, които са вградени в PowerShell, както и всички, които са направени от вашия профил в PowerShell..
- Най- местен обхватът се отнася за каквото и да е настоящият обхват. Когато стартирате PowerShell, тя ще се отнася за глобалния обхват, в рамките на скрипт ще бъде обхвата на скрипта и т.н..
- Най- писменост обхватът се създава, когато се изпълнява скрипт. Единствените команди, които работят в този обхват, са тези, които са в скрипта.
- частен обхватите могат да бъдат дефинирани в рамките на текущия обхват, за да се предотврати възможността за команди в други обхвати да могат да четат или променят елементи, които иначе биха имали достъп до.
Обхватът може да бъде посочен и по номер в определени команди, където настоящият обхват се нарича нула и неговите предци се посочват чрез увеличаване на цели числа. Например, в рамките на скрипт, изпълняван от глобалния обхват, обхватът на скрипта ще бъде 0, а глобалният обхват ще бъде 1. Обхват, който е допълнително вмъкнат в обхвата на скрипта, като функция, ще се отнася за глобалния обхват като 2 Отрицателните числа няма да проработят референтните области на детето - причината за това ще бъде видима скоро.
Как влияят на обхватите командите
Както бе споменато по-рано, командите, изпълнявани в рамките на един обхват, няма да засегнат нещата в друг обхват, освен ако изрично не е заявено това. Например, ако $ MyVar съществува в глобалния обхват и скриптът изпълнява команда за задаване на $ MyVar на различна стойност, глобалната версия на $ MyVar ще остане непроменена, докато копие на $ MyVar се поставя в обхвата на скрипта с новото стойност. Ако $ MyVar не съществува, скриптът ще го създаде в обхвата на скрипта по подразбиране - не в глобалния обхват. Това е важно да запомните, докато научавате за действителната връзка родител / дете между обхватите.
Връзката родител / дете на обхватите в PowerShell е еднопосочна. Командите могат да виждат и по избор да променят текущия обхват, неговия родител и всички обхвати над това. Въпреки това, те не могат да виждат или променят нещата в децата от текущия обхват. Това се дължи главно на това, че след като сте се преместили в родителския обхват, обхватът на детето вече е бил унищожен, защото е изпълнил целта си. Например, защо трябва да виждате или променяте променлива в обхвата на скрипта, от глобалния обхват, след като скриптът е прекратен? Има много случаи, в които се нуждаете от промени в скрипта или функция, които да продължат да съществуват след неговото завършване, но не толкова много, където трябва да направите промени в обекти в обхвата на скрипта или функцията преди или след като бъде стартиран. (Обикновено такива неща ще се обработват като част от скрипта или самата функция.)
Разбира се, какви са правилата без изключения? Едно изключение от горепосочените са частните обхвати. Обектите в частните обхвати са достъпни само за команди, изпълнявани в областта, от която са създадени. Друго важно изключение са елементите, които притежават свойствата на AllScope. Това са специални променливи и псевдоними, за които промяна във всеки обхват ще засегне всички области. Следните команди ще ви покажат кои променливи и псевдоними имат свойствата на AllScope:
Get-Variable | Къде-обект $ _. Опции-съвпадение 'AllScope' Get-Alias | Къде-обект $ _. Опции-съвпадение 'AllScope')
Обхвати в действие
За първия ни поглед върху обхвата в действие, ще започнем в сесия на PowerShell, където променливата $ MyVar е зададена на низ, "Аз съм глобална променлива!" От командния ред. След това, следният скрипт ще бъде стартиран от файл, наречен Scope-Demo.ps1:
Функция FunctionScope 'Промяна на $ MyVar с функция.' $ MyVar = 'Имам зададена от функция!' "MyVar казва $ MyVar" "Проверка на текущата стойност на $ MyVar." "MyVar казва $ MyVar" "Промяна на $ MyVar по сценарий." $ MyVar = 'Получих скрипт!' "MyVar казва $ MyVar" "FunctionScope" Проверка на крайната стойност на MyVar преди изхода на скрипта. " "MyVar казва $ MyVar" "
Ако скриптовете на PowerShell са работили по същия начин като пакетните скриптове, бихме очаквали от $ MyVar (или% MyVar% в пакетния синтаксис) да се промени от „Аз съм глобална променлива!“, Към „Имам зададен от скрипт!“. и най-накрая до "Аз бях зададен от функция!" където ще остане, докато не се промени изрично или сесията се прекрати. Но вижте какво всъщност се случва тук, докато се придвижваме през всеки от обхватите - особено след като функцията FunctionScope завърши работата си и отново проверяваме променливата от Script, а по-късно и от Global,.
Както можете да видите, променливата изглежда се променя, когато се движим през скрипта, защото, докато функцията FunctionScope е завършена, проверяваме променливата от същия обхват, който беше последно променен. След като FunctionScope беше направено, ние се върнахме обратно в обхвата на скрипта, където $ MyVar беше оставен недокоснат от функцията. След това, когато скриптът приключи, се върнахме в Глобалния обхват, където изобщо не беше променен.
Достигане извън локалния обхват
Така че, всичко това е добре и добре да ви помогне да предотвратите случайното прилагане на промени в околната среда извън вашите скриптове и функции, но какво, ако всъщност искате да направите такива промени? Има специален синтаксис за създаване и модифициране на обекти извън локалния обхват. Вие просто поставяте името на обхвата в началото на името на променливата и поставяте двоеточие между имената на обхвата и променливите. Като този:
$ global: MyVar $ script: MyVar $ local: MyVar
Можете да използвате тези модификатори както при гледане, така и при задаване на променливи. Нека видим какво се случва с този демонстрационен скрипт:
Функция FunctionScope "Промяна на $ MyVar в обхвата на локалната функция ... '$ local: MyVar =" Това е MyVar в локалния обхват на функцията. "' Промяна на $ MyVar в обхвата на скрипта ... '$ script: MyVar =' MyVar Сега зададена от функция. "Промяна на $ MyVar в глобалния обхват ..." $ global: MyVar = 'MyVar е зададен в глобалния обхват. Сега задайте от функция. "Проверка на $ MyVar във всеки обхват ..." "Локално: $ local: MyVar" "Скрипт: $ script: MyVar" "Global: $ global: MyVar" "" Получаване на текущата стойност на $ MyVar. " "MyVar казва $ MyVar" "Промяна на $ MyVar по сценарий." $ MyVar = 'Получих скрипт!' "MyVar казва $ MyVar" FunctionScope "Проверка на $ MyVar от обхвата на скрипта преди излизане." "MyVar казва $ MyVar" "
Както и преди, ще започнем с поставяне на променливата в глобалния обхват и ще завършим с проверка на крайния резултат от глобалния обхват.
Тук можете да видите, че FunctionScope е успял да промени променливата в обхвата на скрипта и да промени промените след като е бил завършен. Също така, промяната в променливата в глобалния обхват продължава дори след излизането на скрипта. Това може да бъде особено полезно, ако се налага многократно да променяте променливи в скрипт или в рамките на глобалния обхват, като използвате същия код - просто дефинирате функция или скрипт, който е написан, за да модифицирате променливата, където и как се нуждаете от нея, и призовавайте това, когато тези промени са необходими.
Както бе споменато по-рано, номерата на обхвата могат да се използват и в определени команди за модифициране на променливата на различни нива по отношение на локалния обхват. Ето един и същ скрипт, използван във втория пример по-горе, но с модифицирана функция, за да използвате командите Get-Variable и Set-Variable с номера на обхвата, вместо директно рефериране на променливата с имената на обхвати:
Функция FunctionScope "Промяна на $ MyVar в обхват 0, по отношение на FunctionScope…" Set-Variable MyVar "Това е MyVar в обхвата на функцията 0." -Обхват 0 'Промяна на $ MyVar в обхват 1, по отношение на FunctionScope ... "Set-Variable MyVar 'MyVar беше променен в обхват 1, от функция.' -Scope 1 'Промяна на $ MyVar в обхват 2, по отношение на функционалността…' Set-Variable MyVar 'MyVar е променен в обхват 2, от функция.' -Обхват 2 "Проверка на $ MyVar във всеки обхват ..." Обхват 0: "Вземете-променлива MyVar -Scope 0 -ValueOnly" Обхват 1: "Get-Variable MyVar -Scope 1 -ValueOnly" Обхват 2: 'Get-Variable MyVar -Scope 2 -ValueOnly "" Получаване на текущата стойност на $ MyVar. " "MyVar казва $ MyVar" "Промяна на $ MyVar по сценарий." $ MyVar = 'Получих скрипт!' "MyVar казва $ MyVar" FunctionScope "Проверка на $ MyVar от обхвата на скрипта преди излизане." "MyVar казва $ MyVar" "
Подобно на преди, тук можем да видим как команди в един обхват могат да променят обекти в родителския си обхват.
Допълнителна информация
Все още има много повече неща, които могат да бъдат направени с обхвати, отколкото може да се побере в тази статия. Обхватите засягат повече от променливи и има още какво да се научи за частните обхвати и променливите на AllScope. За повече полезна информация можете да изпълните следната команда от PowerShell:
Get-Help about_scopes
Същият файл за помощ е достъпен и в TechNet.
Обхват на изображението: spadassin на openclipart