PowerShell - как проверить значение переменной с помощью Set-StrictMode -version latest?

Я только начал писать сценарии PowerShell, и у меня возникла проблема с проверкой значений переменных. Я стараюсь запускать все со всеми включенными предупреждениями, особенно пока учусь, чтобы отлавливать глупые ошибки. Итак, я использую CTPV3 и устанавливаю строгий режим с помощью "set-strictmode -version latest". Но я нахожусь в затруднительном положении с проверкой значений входящих переменных. Эти переменные могут быть или не могут быть уже установлены.

# all FAIL if $var is undefined under "Set-StrictMode -version latest"
if ( !$var ) { $var = "new-value"; } 
if ( $var -eq $null ) { $var = "new-value"; } 

Я не могу найти способ проверить, имеет ли переменная значение, которое не вызывает предупреждений при отсутствии переменной, если я не отключу строгий режим. И я не хочу постоянно включать и выключать строгий режим только для проверки переменных. Я уверен, что забыл бы включить его где-нибудь, и он выглядит ужасно захламленным. Это не может быть правдой. Что мне не хватает?


person user62129    schedule 04.02.2009    source источник


Ответы (2)


Вы действительно проверяете здесь две вещи: существование и ценность. И тест существования - это тот, который вызывает предупреждения при работе в строгом режиме. Итак, разделите тесты. Помня о том, что PowerShell рассматривает переменные как просто еще один поставщик (точно так же, как поставщик файлов или реестра) и что все переменные PowerShell существуют как файлы в корневой папке на диске называется "переменная:", становится очевидным, что вы можете использовать тот же механизм, который вы обычно использовали бы для проверки существования любого другого файла. Следовательно, используйте test-path:

if (!(test-path variable:\var)) {$var = $null} # test for EXISTENCE & create
if ( !$var ) { $var = "new-value"; }           # test the VALUE

Обратите внимание, что текущий строгий режим можно изменить в дочерних областях, не затрагивая родительскую область (например, в блоках сценариев). Итак, вы можете написать блок скрипта, который инкапсулирует удаление строгого режима и установку переменной, не влияя на строгость окружающей программы. Это немного сложно из-за переменной области видимости. Я могу думать о двух возможностях:

# 1 - вернуть значение из блока скрипта

$var = & { Set-StrictMode -off; switch( $var ) { $null { "new-value" } default { $var } }}

или # 2 - используйте модификаторы области видимости

& { Set-StrictMode -off; if (!$var) { set-variable -scope 1 var "new-value" }}

Вероятно, худшая часть этого - подверженное ошибкам повторяющееся использование $ var (как с начальным символом $, так и без него). Кажется, что это очень подвержено ошибкам. Итак, вместо этого я бы использовал подпрограмму:

function set-Variable-IfMissingOrNull ($name, $value)
{
$isMissingOrNull = !(test-path ('variable:'+$name)) -or ((get-variable $name -value) -eq $null)
if ($isMissingOrNull) { set-variable -scope 1 $name $value }
}
set-alias ?? set-Variable-IfMissingOrNull
#...
## in use, must not have a leading $ or the shell attempts to read the possibly non-existant $var
set-VarIfMissingOrNull var "new-value"
?? varX 1

Последнее, вероятно, я бы написал в сценарии.

РЕДАКТИРОВАТЬ: Поразмыслив над вашим вопросом еще немного, я придумал более простую функцию, которая больше соответствует вашему стилю кодирования. Попробуйте эту функцию:

function test-variable
{# return $false if variable:\$name is missing or $null
param( [string]$name )
$isMissingOrNull = (!(test-path ('variable:'+$name)) -or ((get-variable -name $name -value) -eq $null))
return !$isMissingOrNull
}
set-alias ?-var test-variable
if (!(?-var var)) {$var = "default-value"}

Надеюсь, это поможет.

person rivy    schedule 04.02.2009
comment
Пожалуйста, примите этот ответ. Рой отлично поработал, чтобы дать вам ответ. Он заслуживает похвалы за это. - person EBGreen; 05.02.2009
comment
Обновлен ответ, чтобы отразить поведение PowerShell для параметров пустой строки, оцениваемых как false - person arberg; 15.02.2019

Во-первых, мне нравится ответ Роя, полный и сжатый. Я просто хотел упомянуть, что похоже, что вы пытаетесь установить переменную, только если она уже установлена. Это похоже на работу с переменными только для чтения или константами.

Чтобы сделать переменную постоянной только для чтения, используйте

Set-Variable

От get-help Set-Variable -full

-- ReadOnly: Cannot be deleted or changed without the Force parameter.
-- Constant: Cannot be deleted or changed. Constant is valid only when
creating a new variable. You cannot set the Constant option on an
existing variable.
person EdgeVB    schedule 13.02.2009