什么';这两个词之间有什么区别$myvariable=";并在PowerShell中设置变量?
当我学习PowerShell脚本语言时,我尝试使用“Write Output”命令来显示变量 我使用不同的方法来创建变量 例如:什么';这两个词之间有什么区别$myvariable=";并在PowerShell中设置变量?,powershell,Powershell,当我学习PowerShell脚本语言时,我尝试使用“Write Output”命令来显示变量 我使用不同的方法来创建变量 例如: $myvariable=0x5555 设置变量-名称myvariable2-值0x5555 这两个变量的数据类型为Int32 当我使用下面的命令时 写入输出$myvariable$myvariable2 结果是21845和0x5555 这两个变量之间有什么不同 如何显示格式结果,如printf%d%x 第一个问题已由@PetSerAl在评论中回答。你的第二个问题: 如
$myvariable=0x5555
设置变量-名称myvariable2-值0x5555
这两个变量的数据类型为Int32
当我使用下面的命令时
写入输出$myvariable$myvariable2
结果是21845
和0x5555
这两个变量之间有什么不同
如何显示格式结果,如
printf%d%x
第一个问题已由@PetSerAl在评论中回答。你的第二个问题:
如何显示格式结果,如printf%d%x
使用PowerShell获得所需的结果。与以前一样,在评论中给出了关键指针(后来帮助改进了此答案):
从PowerShell Core 6.2.0开始编写
PowerShell将看似数字的无引号文字参数解析为数字,并将其包装在“半透明”的[psobject]
实例中,该实例的目的也是将指定为字符串的确切参数保留下来
所谓半透明,我的意思是生成的$myVariable2
:
- 主要是一个数字——一个用于计算的常规(未包装的)
实例;e、 例如,[int]
正确返回$myVariable2+1
21846
- 此外,当您使用
或通过.GetType()
cmdlet请求其类型时,它会显示它是一个数字;换句话说:在本例中,PowerShell假装包装器不在那里(请参阅下面的解决方法)Get Member
- 此外,当您使用
- 在以下上下文中,情景行为类似于字符串——完全按照指定返回原始参数文本:
- 输出格式,无论是直接打印到控制台时,还是通常使用
cmdlet,例如Out-*
(但不是Out File
)和Set Content
cmdletFormat-*
- 字符串格式设置为(基于.NET;例如,
相当于'答案为{0}'-f 42
)[string]::Format('答案为{0}',42)
- 令人惊讶的是,它的行为不像可扩展字符串(
)中的字符串,当您调用“$myVariable2”
方法(.ToString()
)并(因此也)使用$myVariable2.ToString()
设置内容时
- 但是,可以使用
$myVariable2.psobject.ToString()
- 但是,可以使用
- 输出格式,无论是直接打印到控制台时,还是通常使用
1.0
之类的参数可以解释为版本字符串或浮点数
PowerShell解决歧义的方法是将这样一个标记解析为一个数字,然而,它在特定情况下充当字符串[1],如上所示
通过键入参数以指示绑定到它的参数是字符串还是数字,可以完全避免歧义
但是,Set Variable
和New Variable
cmdlet的-Value
参数必须是类型化的,因为它必须能够接受任何类型的值,并且这些cmdlet没有一个参数可以让您指示所需的数据类型
解决方案是通过将
(…)
参数括在(…)中,强制将-Value
参数视为表达式的结果,而不是不带引号的文字参数:
# Due to enclosing in (...), the value that is stored in $myvariable2
# is *not* wrapped in [psobject] and therefore behaves the same as
# $myvariable = 0x55555
Set-Variable -Name myvariable2 -Value (0x5555)
# OK: $myvariable isn't wrapped in [psobject], so formatting it as a
# hex. number works as expected:
PS> 'hex: 0x{0:x}' -f $myvariable
hex: 0x5555 # OK: Literal '0x' followed by hex. representation of the [int]
# !! Does NOT work as expected, because $myvariable2 is treated as a *string*
# !! That is, {0:x} is effectively treated as just {0}, and the string
# !! representation stored in the [psobject] wrapper is used as-is.
PS> 'hex: 0x{0:x}' -f $myvariable2
hex: 0x0x5555 # !! Note the extra '0x'
# Workaround 1: Use a *cast* (with the same type) to force creation of
# a new, *unwrapped* [int] instance:
PS> 'hex: 0x{0:x}' -f [int] $myvariable2
hex: 0x5555 # OK
# Workaround 2: Access the *wrapped* object via .psobject.BaseObject.
# The result is an [int] that behaves as expected.
PS> 'hex: 0x{0:x}' -f $myvariable2.psobject.BaseObject
hex: 0x5555 # OK
相反,如果不应用上述解决方案,则有两个选项可用于按需展开的$myvariable2
's value on demand:
# Due to enclosing in (...), the value that is stored in $myvariable2
# is *not* wrapped in [psobject] and therefore behaves the same as
# $myvariable = 0x55555
Set-Variable -Name myvariable2 -Value (0x5555)
# OK: $myvariable isn't wrapped in [psobject], so formatting it as a
# hex. number works as expected:
PS> 'hex: 0x{0:x}' -f $myvariable
hex: 0x5555 # OK: Literal '0x' followed by hex. representation of the [int]
# !! Does NOT work as expected, because $myvariable2 is treated as a *string*
# !! That is, {0:x} is effectively treated as just {0}, and the string
# !! representation stored in the [psobject] wrapper is used as-is.
PS> 'hex: 0x{0:x}' -f $myvariable2
hex: 0x0x5555 # !! Note the extra '0x'
# Workaround 1: Use a *cast* (with the same type) to force creation of
# a new, *unwrapped* [int] instance:
PS> 'hex: 0x{0:x}' -f [int] $myvariable2
hex: 0x5555 # OK
# Workaround 2: Access the *wrapped* object via .psobject.BaseObject.
# The result is an [int] that behaves as expected.
PS> 'hex: 0x{0:x}' -f $myvariable2.psobject.BaseObject
hex: 0x5555 # OK
检测[psobject]
-包装值:
最简单的解决方案是使用-is[psobject]
:
PS> $myvariable -is [psobject]
False # NO wrapper object
PS> $myvariable2 -is [psobject]
True # !! wrapper object
(PetSerAl提供了以下不太明显的替代方案:[Type]::GetTypeArray((,$myvariable2))
,它绕过了PowerShell隐藏包装程序的诡计。)
[1] 在作为命令参数传递的隐式类型数字中保留输入字符串表示形式:
# Due to enclosing in (...), the value that is stored in $myvariable2
# is *not* wrapped in [psobject] and therefore behaves the same as
# $myvariable = 0x55555
Set-Variable -Name myvariable2 -Value (0x5555)
# OK: $myvariable isn't wrapped in [psobject], so formatting it as a
# hex. number works as expected:
PS> 'hex: 0x{0:x}' -f $myvariable
hex: 0x5555 # OK: Literal '0x' followed by hex. representation of the [int]
# !! Does NOT work as expected, because $myvariable2 is treated as a *string*
# !! That is, {0:x} is effectively treated as just {0}, and the string
# !! representation stored in the [psobject] wrapper is used as-is.
PS> 'hex: 0x{0:x}' -f $myvariable2
hex: 0x0x5555 # !! Note the extra '0x'
# Workaround 1: Use a *cast* (with the same type) to force creation of
# a new, *unwrapped* [int] instance:
PS> 'hex: 0x{0:x}' -f [int] $myvariable2
hex: 0x5555 # OK
# Workaround 2: Access the *wrapped* object via .psobject.BaseObject.
# The result is an [int] that behaves as expected.
PS> 'hex: 0x{0:x}' -f $myvariable2.psobject.BaseObject
hex: 0x5555 # OK
与传统Shell不同,PowerShell使用了丰富的类型,因此像01.2
这样的参数文本会立即解析为数字-在这种情况下,a[double]
,如果按原样使用,则会导致输出上的不同表示形式,因为-一旦解析为数字-默认输出格式应用于输出(其中数字必须再次转换为字符串):
但是,目标命令的最终目的可能是将参数视为字符串,在这种情况下,您不希望更改输出表示形式。
(请注意,虽然您可以通过使用引号(01.2
vs.'01.2'
)消除字符串中的数字歧义,但在命令参数中通常不需要引号,这与在传统shell中不需要引号的方式相同。)
正是由于这个原因,[psobject]
包装器用于捕获原始字符串表示并在输出时使用它
注意:可以说,更一致的方法是始终将无引号的文字参数视为字符串,除非绑定到PowerShell命令中的显式数字类型参数。
这是调用外部程序的必要条件,外部程序的参数只能作为字符串传递
也就是说,在初始