Jos*_*nho 7 powershell arguments
我一直在敲着头,这件事……
创建了这个简单的 PowerShell 脚本:
测试.ps1:
Write-Host $args[0]
Write-Host $($args[0])
Write-Host "$($args[0])"
Run Code Online (Sandbox Code Playgroud)
现在,使用以下参数运行脚本两次:
powershell .\test.ps1 0E2C
powershell .\test.ps1 0E2D
Run Code Online (Sandbox Code Playgroud)
第一次运行返回:
0E2C
0E2C
0E2C
Run Code Online (Sandbox Code Playgroud)
第二次运行返回:
0E2D
0
0
Run Code Online (Sandbox Code Playgroud)
这是为什么 ?为什么 powershell 将 0E2D 转换为 0 ?是否考虑到 0E2D 是一个十六进制值并尝试以某种方式转换它?但为什么,为什么它不对值 0E2C 做同样的事情呢?
编辑:谢谢大家。
我通过使用变量解决了这个问题,并强制它为字符串因此,更改我的 TEST.PS1 :
Write-Host $args[0]
Write-Host $($args[0])
Write-Host "$($args[0])"
[string] $myvar = $args[0]
Write-Host "$myvar"
Run Code Online (Sandbox Code Playgroud)
现在,当我跑步时:
powershell .\test.ps1 0E2D
Run Code Online (Sandbox Code Playgroud)
我现在得到:
0E2D
0
0
0E2D
Run Code Online (Sandbox Code Playgroud)
太长了;博士
诸如此类的未加引号的参数0E2D本质上是不明确的- 它可以被解释为字符串或数字。默认情况下,它被解析为数字,但原始表示形式被缓存- 请参阅下一节。
为避免歧义:
现有的、有用的答案解释说 ,0E2D被解释为数字文字,即科学(指数)表示法中的十进制值,[decimal]由于后缀 D而键入为 a (d也可以工作,因为类型说明符后缀通常不区分大小写)。
让我通过解释为什么$args[0]仍然显示参数的原始字符串表示来补充它们,至少在按原样使用时是这样。
在参数 解析模式下,即当参数传递给命令时,简单的字符串值(既不包含空格也不包含其他 shell 元字符的值)不需要加引号。
这会产生歧义,例如在当前的情况下:是0E2D数字,还是字符串()'0E2D'?
PowerShell 的参数(参数)解析器按如下方式处理这种歧义:
如果不带引号的参数可以被解析为数字,那么它就是。
如果是这样,并且如果数字的默认字符串化不等于指定的参数,则该数字将被包装在一个(大部分不可见)[psobject]实例中,该实例缓存原始(字符串)表示形式,可以通过以下方式调用.psobject.ToString()
如果不带引号的参数绑定到显式声明的类型参数,则最初解析的形式最终无关紧要,但它在未绑定参数传递中确实很重要,即在没有预先声明的参数的情况下通过自动$args变量按位置传递参数。
这是一个使用1L位置未绑定参数的显式说明,它被解析为[long]value 1,原始表示形式1L缓存在[psobject]包装器中:
PS> & { $args[0].ToString(), $args[0].psobject.ToString() } 1L
1 # default stringification of the [long] value that 1L was parsed as
1L # original representation
Run Code Online (Sandbox Code Playgroud)
默认显示表示隐式调用.psobject.ToString():
PS> & { $args[0] } 1L
1L # original representation - even though it was parsed as [long]
Run Code Online (Sandbox Code Playgroud)
值得称赞的是,这在将参数传递给外部程序时也适用,因为 PowerShell 不应该假设参数是否代表数字 - 这是由目标程序决定的:
PS> cmd /c echo 1L
1L # original representation
Run Code Online (Sandbox Code Playgroud)
然而不幸的是 - 正如你的问题所示 - Windows PowerShell和PowerShell (Core)从 v7.2.6 开始 -在它们遵守缓存的字符串表示形式方面不一致:
& {
$args[0] # ditto for ($args[0])
$($args[0]) # ditto for @($args[0])
"$($args[0])"
} 1L
Run Code Online (Sandbox Code Playgroud)
可以说,所有这些命令都应该遵循原始表示形式,但只有其中一些命令这样做:
1L
1L
1
Run Code Online (Sandbox Code Playgroud)
正如0E2D您的问题一样,两个 PowerShell 版本甚至表现出差异:Windows PowerShell中的打印与PowerShell (Core) 7.2.6中的$($args[0])打印。0O2ED
另一个不一致之处是,如果将这样的参数传递给-f格式运算符,则只有缓存的字符串表示形式受到尊重,而不是参数实际解析为的数字类型:
PS> & { '{0:N1}' -f $args[0] } 1.234e0 # Argument is parsed as a [double]
1.234e0 # !! Formatting the [double] as a number with 1 decimal place failed.
Run Code Online (Sandbox Code Playgroud)
然而,这种行为被声明为设计使然- 请参阅GitHub 问题 #17199。
| 归档时间: |
|
| 查看次数: |
79 次 |
| 最近记录: |