1

假设我有以下testArgsX.ps1文件:

$ARG_X_PARAMETER=1
If ($args[0] -ne "") {
    echo ARGS[X]="`"$args[0]`""
    $ARG_X_PARAMETER=$args[0]
}
echo ARG_X_PARAMETER=$ARG_X_PARAMETER

当我在命令提示符 ( C:\Test> powershell .\testArgsX.ps1) 或 PowerShell 提示符 ( PS C:\Test> .\testArgsX.ps1) 中执行它时,它会输出以下内容:

ARGS[X]="[0]"
ARG_X_PARAMETER=

在 if 条件中,似乎$args[0]没有被解释为标量值。虽然我知道有两种方法可以规避这个问题(如下所示)。我想知道为什么它不将其解释为标量值,以及是否有办法解决它。

  1. 取出整个 if 语句 ( If ( ... ) { ... }) 并替换为Param ( [Int]$RUN_JUST_ONCE = 1 )
  2. 将 if 条件从更改If ($args[0] -ne "") {If ($args.Length -gt 0) {
4

1 回答 1

1

$args[0] 一个标量,但在 PowerShell 中访问不存在的数组元素$null会返回[1],并且$null确实等于空字符串(""'')。

  • 因此,您应该测试$null.

    • 请注意,$null最好通过放置$nullLHS ( ) 上进行测试,因为在 RHS 上,如果另一个操作数恰好是数组$null -ne $args[0],它将充当过滤器而不是返回布尔值
  • 另外,请注意,为了使用诸如inside之类的表达式,一个可扩展(插值)字符串,您必须使用$args[0]"..."$()表达式运算符; 没有它,$args作为一个整体被扩展,并被逐字[0]使用- 看到这个答案

  • echo是 cmdlet 的内置别名,Write-Output很少需要显式使用;简单地使用其输出既不被捕获也不被重定向的命令或表达式是隐式输出的。

把它们放在一起:

$ARG_X_PARAMETER=1
If ($null -ne $args[0]) {
    "ARGS[X]=`"$($args[0])`""
    $ARG_X_PARAMETER=$args[0]
}

"ARG_X_PARAMETER=$ARG_X_PARAMETER"

或者,为您的脚本声明参数,这也使得分配默认值变得容易:

param(
  # This implicitly becomes the 1st positional parameter.
  $ARG_X_PARAMETER = 1
)

"ARG_X_PARAMETER=$ARG_X_PARAMETER"

默认情况下,参数是positional的,这意味着它们可以在未命名的情况下使用(例如testArgsX.ps1 42),尽管显式使用名称始终是一个选项(例如
testArgsX.ps1 -ARG_X_PARAMETER 42) - 尽管可能需要更好的名称。

PowerShell 可选地允许您将数据类型分配给参数并使用各种属性,尤其是用于参数验证的属性。

请参阅about_Functionsabout_Functions_Advanced_Parameters


[1]Set-StrictMode -Version 3在效果或更高的情况下,访问不存在的元素会导致语句终止错误

于 2020-12-02T03:52:03.943 回答