我刚刚开始做一些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"; }
我无法找到一种方法来测试变量是否具有在变量丢失时不会引起警告的值,除非我关闭严格模式。而且我不想在整个地方打开和关闭严格模式来测试变量。我确定我会忘记在某个地方把它转回来,它看起来非常混乱。这不可能是正确的。我错过了什么?
答案 0 :(得分:41)
你真的在这里测试两件事,存在和价值。存在测试是在严格模式操作下引起警告的测试。所以,分开测试。请记住,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"}
希望有所帮助。
答案 1 :(得分:3)
首先,我喜欢罗伊的回答,完整而简洁。我只是想提一下,如果你已经设置了变量,你似乎只想设置一个变量。对于只读变量或常量来说,这似乎是一项工作。
要使变量为只读,常量,请使用
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.