什么';这两个词之间有什么区别$myvariable=";并在PowerShell中设置变量?

什么';这两个词之间有什么区别$myvariable=";并在PowerShell中设置变量?,powershell,Powershell,当我学习PowerShell脚本语言时,我尝试使用“Write Output”命令来显示变量 我使用不同的方法来创建变量 例如: $myvariable=0x5555 设置变量-名称myvariable2-值0x5555 这两个变量的数据类型为Int32 当我使用下面的命令时 写入输出$myvariable$myvariable2 结果是21845和0x5555 这两个变量之间有什么不同 如何显示格式结果,如printf%d%x 第一个问题已由@PetSerAl在评论中回答。你的第二个问题: 如

当我学习PowerShell脚本语言时,我尝试使用“Write Output”命令来显示变量

我使用不同的方法来创建变量

例如:

$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

  • 主要是一个数字——一个用于计算的常规(未包装的)
    [int]
    实例;e、 例如,
    $myVariable2+1
    正确返回
    21846

    • 此外,当您使用
      .GetType()
      或通过
      Get Member
      cmdlet请求其类型时,它会显示它是一个数字;换句话说:在本例中,PowerShell假装包装器不在那里(请参阅下面的解决方法)
  • 在以下上下文中,情景行为类似于字符串——完全按照指定返回原始参数文本:

    • 输出格式,无论是直接打印到控制台时,还是通常使用
      Out-*
      cmdlet,例如
      Out File
      (但不是
      Set Content
      )和
      Format-*
      cmdlet

    • 字符串格式设置为(基于.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命令中的显式数字类型参数。

这是调用外部程序的必要条件,外部程序的参数只能作为字符串传递

也就是说,在初始