Как Scopes влияют на сценарии PowerShell

Оглавление:

Как Scopes влияют на сценарии PowerShell
Как Scopes влияют на сценарии PowerShell

Видео: Как Scopes влияют на сценарии PowerShell

Видео: Как Scopes влияют на сценарии PowerShell
Видео: ЗАСТАВЬ СВОЙ ТЕЛЕФОН ЛЕТАТЬ! Как очистить память на смартфоне и удалить ненужное навсегда! - YouTube 2024, Апрель
Anonim
В пакетных сценариях изменения в переменных среды оказывают глобальное влияние на текущий сеанс по умолчанию. Для PowerShell истинная противоположность истинна, поскольку области используются для изоляции изменений скрипта. Здесь мы рассмотрим, как области действия влияют на сценарии PowerShell и как работать в них и вокруг них.
В пакетных сценариях изменения в переменных среды оказывают глобальное влияние на текущий сеанс по умолчанию. Для PowerShell истинная противоположность истинна, поскольку области используются для изоляции изменений скрипта. Здесь мы рассмотрим, как области действия влияют на сценарии PowerShell и как работать в них и вокруг них.

Что такое область?

В PowerShell «область» относится к текущей среде, в которой работает скрипт или командная оболочка. Области используются для защиты определенных объектов внутри среды от непреднамеренного изменения сценариев или функций. В частности, следующие вещи защищены от модификации командами, запущенными из другой области действия, если не указано иное параметрами в этих командах:

  • переменные
  • Псевдонимы
  • функции
  • Приводы PowerShell (PSDrives)

Новые области создаются при каждом запуске скрипта или функции или при создании нового сеанса или экземпляра PowerShell. Области, созданные при выполнении сценариев и функций, имеют отношение «родительский / дочерний» к сфере, из которой они были созданы. Есть несколько областей, которые имеют особенно специальные значения и могут быть доступны по имени:

  • Глобальный scope - область, которая создается при запуске PowerShell. Он включает в себя переменные, псевдонимы, функции и PSDrives, встроенные в PowerShell, а также любые, которые создаются профилем PowerShell.
  • Местный область действия относится к любой текущей области. Когда вы запустите PowerShell, он будет ссылаться на глобальную область, внутри скрипта будет область действия сценария и т. Д.
  • скрипт область создается при запуске скрипта. Единственными командами, которые работают в этой области, являются те, которые находятся в скрипте.
  • Частный области могут быть определены в пределах текущей области, чтобы команды из других областей не могли читать или изменять элементы, к которым они могли бы иметь доступ.

Области могут также упоминаться числом в определенных командах, где текущая область действия называется нулевой, а ее предки ссылаются путем увеличения целых чисел. Например, в сценарии, запущенном из Глобальной области видимости, область сценария будет равна 0, а глобальная область будет равна 1. Область, которая была дополнительно вложена в область сценария, например, функция, будет ссылаться на глобальную область как 2 Отрицательные числа не будут работать, чтобы ссылаться на дочерние области - причина этого будет очевидна в ближайшее время.

Как влиять на действия с помощью Scopes

Как упоминалось ранее, команды, выполняемые в рамках одной области действия, не будут влиять на вещи в другой области, если только это специально не сказано. Например, если $ MyVar существует в глобальной области и сценарий запускает команду для установки $ MyVar на другое значение, глобальная версия $ MyVar останется неизменной, а копия $ MyVar будет помещена в область сценария с новым значение. Если $ MyVar не существует, скрипт создаст его в области сценария по умолчанию - не в глобальной области. Это важно помнить, когда вы узнаете о фактических взаимоотношениях между родителями и детьми между областями.

Родственные / дочерние отношения областей в PowerShell являются односторонними. Команды могут видеть и, возможно, изменять текущую область действия, ее родительский элемент и любые области выше. Тем не менее, они не могут видеть или изменять вещи у любых детей текущей области. Это связано прежде всего с тем, что после того, как вы перешли в родительскую область, дочерняя область уже уничтожена, поскольку она выполнила свою задачу. Например, почему вы должны увидеть или изменить переменную в области сценария, из глобальной области, после завершения сценария? Существует множество случаев, когда вам нужно, чтобы изменения скрипта или функции сохранялись за пределами его завершения, но не так много, где вам нужно было бы вносить изменения в объекты внутри области действия сценария или функции до или после ее запуска. (Обычно такие вещи будут обрабатываться как часть самого скрипта или функции).

Конечно, что такое правила без исключений? Единственное исключение из этого выше - частные области. Объекты в частных областях доступны только для команд, запущенных в области, из которой они были созданы. Другим важным исключением являются элементы, обладающие свойством AllScope. Это специальные переменные и псевдонимы, для которых изменение в любой области затронет все области. Следующие команды покажут вам, какие переменные и псевдонимы имеют свойство AllScope:

Get-Variable | Where-Object {$_.Options -match 'AllScope'} Get-Alias | Where-Object {$_.Options -match 'AllScope')

Области действия

Для нашего первого взгляда на области действия в действии мы собираемся начать в сеансе PowerShell, где переменная $ MyVar была установлена в строку «Я глобальная переменная!» Из командной строки. Затем следующий сценарий будет запущен из файла Scope-Demo.ps1:

Function FunctionScope { 'Changing $MyVar with a function.' $MyVar = 'I got set by a function!' 'MyVar says $MyVar' } '' 'Checking current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' '' FunctionScope '' 'Checking final value of MyVar before script exit.' 'MyVar says $MyVar' ''

Если скрипты PowerShell работали так же, как и пакетные скрипты, мы ожидали бы, что переменная $ MyVar (или% MyVar% в пакетном синтаксисе) изменится с «Я глобальная переменная!», Чтобы «я был установлен скриптом!»., и, наконец, до «Я получил функцию!», где он будет оставаться до тех пор, пока он не будет явно изменен или сеанс не будет завершен. Однако посмотрите, что на самом деле происходит здесь, когда мы перемещаемся по каждой из областей - в частности, после того, как функция FunctionScope завершила свою работу, и мы снова проверим переменную из скрипта, а затем глобального.

Как вы видите, переменная, по-видимому, изменилась, когда мы перешли через скрипт, потому что, пока функция FunctionScope не была завершена, мы проверяли переменную из той же области, в которой она была в последний раз изменена. После того, как функция FunctionScope была выполнена, мы вернулись в область сценария, где функция $ MyVar осталась нетронутой функцией. Затем, когда сценарий завершился, мы вернулись в глобальную область, где она вообще не была изменена.
Как вы видите, переменная, по-видимому, изменилась, когда мы перешли через скрипт, потому что, пока функция FunctionScope не была завершена, мы проверяли переменную из той же области, в которой она была в последний раз изменена. После того, как функция FunctionScope была выполнена, мы вернулись в область сценария, где функция $ MyVar осталась нетронутой функцией. Затем, когда сценарий завершился, мы вернулись в глобальную область, где она вообще не была изменена.

Достижение вне локального масштаба

Таким образом, все это хорошо и полезно, чтобы помочь вам избежать случайного применения изменений в среде помимо ваших скриптов и функций, но что, если вы действительно хотите сделать такие изменения? Существует особый и довольно простой синтаксис для создания и модификации объектов за пределами локальной области. Вы просто поместите имя области в начале имени переменной и поместите двоеточие между областью и именами переменных. Как это:

$global:MyVar $script:MyVar $local:MyVar

Эти модификаторы можно использовать как при просмотре, так и при настройке переменных. Давайте посмотрим, что происходит с этим демонстрационным скриптом:

Function FunctionScope { '' 'Changing $MyVar in the local function scope…' $local:MyVar = 'This is MyVar in the function's local scope.' 'Changing $MyVar in the script scope…' $script:MyVar = 'MyVar used to be set by a script. Now set by a function.' 'Changing $MyVar in the global scope…' $global:MyVar = 'MyVar was set in the global scope. Now set by a function.' '' 'Checking $MyVar in each scope…' 'Local: $local:MyVar' 'Script: $script:MyVar' 'Global: $global:MyVar' '' } '' 'Getting current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' FunctionScope 'Checking $MyVar from script scope before exit.' 'MyVar says $MyVar' ''

Как и раньше, мы начнем с установки переменной в глобальном масштабе и заканчивая проверкой окончательного результата Глобальной области.

Здесь вы можете видеть, что FunctionScope смог изменить переменную в области сценария, и изменения сохраняются после ее завершения. Кроме того, изменение переменной в Глобальной области сохранялось даже после выхода сценария. Это может быть особенно полезно, если вам нужно многократно изменять переменные в сценарии или в пределах глобальной области, используя тот же код, - вы просто определяете функцию или скрипт, который написан для изменения переменной где и как вам это нужно и призывать к этому, когда эти изменения необходимы.
Здесь вы можете видеть, что FunctionScope смог изменить переменную в области сценария, и изменения сохраняются после ее завершения. Кроме того, изменение переменной в Глобальной области сохранялось даже после выхода сценария. Это может быть особенно полезно, если вам нужно многократно изменять переменные в сценарии или в пределах глобальной области, используя тот же код, - вы просто определяете функцию или скрипт, который написан для изменения переменной где и как вам это нужно и призывать к этому, когда эти изменения необходимы.

Как упоминалось ранее, номера областей также могут использоваться в некоторых командах для изменения переменной на разных уровнях по отношению к локальной области. Вот тот же сценарий, который использовался во втором примере выше, но с функцией, измененной для использования команд Get-Variable и Set-Variable с номерами областей, а не прямой ссылкой на переменную с именованными областями:

Function FunctionScope { '' 'Changing $MyVar in scope 0, relative to FunctionScope…' Set-Variable MyVar 'This is MyVar in the function's scope 0.' –Scope 0 'Changing $MyVar in scope 1, relative to FunctionScope…' Set-Variable MyVar 'MyVar was changed in scope 1, from a function.' –Scope 1 'Changing $MyVar in scope 2, relative to Functionscope…' Set-Variable MyVar 'MyVar was changed in scope 2, from a function.' –Scope 2 '' 'Checking $MyVar in each scope…' ‘Scope 0:’ Get-Variable MyVar –Scope 0 –ValueOnly ‘Scope 1:’ Get-Variable MyVar –Scope 1 –ValueOnly ‘Scope 2:’ Get-Variable MyVar –Scope 2 –ValueOnly '' } '' 'Getting current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' FunctionScope 'Checking $MyVar from script scope before exit.' 'MyVar says $MyVar' ''

Image
Image

Как и раньше, мы можем видеть, как команды в одной области могут изменять объекты в своей родительской области.

Дополнительная информация

Там все еще гораздо больше, что можно сделать с помощью областей, чем может поместиться в этой статье. Области действия влияют не только на переменные, но и на частные области и переменные AllScope еще многое предстоит узнать. Для получения более полезной информации вы можете запустить следующую команду из PowerShell:

Get-Help about_scopes

Тот же файл справки также доступен в TechNet.

Масштаб изображения кредита: spadassin on openclipart

Рекомендуемые: