Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 为什么我的脚本块在执行时被视为字符串,而不是作为脚本执行?_Powershell - Fatal编程技术网

Powershell 为什么我的脚本块在执行时被视为字符串,而不是作为脚本执行?

Powershell 为什么我的脚本块在执行时被视为字符串,而不是作为脚本执行?,powershell,Powershell,我希望下面的脚本块执行并返回类型为byte和int的数字,但是引号内的所有内容都变成了字符串而不是脚本 $a=(&{Param($t);"[$t]`$num=10;`$num+=2;`$num"} byte) $a # OUTPUTS STRING [byte]$num=10;$num+=2;$num # NOT NUMBER 12 $ty="int" $b=(&{"[$ty]`$num=5;`$num+=2;`$num"}) $b # OUTPUTS STRING [int]

我希望下面的脚本块执行并返回类型为
byte
int
的数字,但是引号内的所有内容都变成了字符串而不是脚本

$a=(&{Param($t);"[$t]`$num=10;`$num+=2;`$num"} byte)
$a
# OUTPUTS STRING [byte]$num=10;$num+=2;$num
# NOT NUMBER 12

$ty="int"
$b=(&{"[$ty]`$num=5;`$num+=2;`$num"})
$b
# OUTPUTS STRING [int]$num=5;$num+=2;$num
# NOT NUMBER 7
我如何使它按预期工作? 谢谢

当您用引号括起来时(请参阅),您正在创建一个字符串:

"[$t]`$num=10;`$num+=2;`$num"
因为这是你们正在组装的,这是你们正在返回的


我假设您正在尝试强制转换为特定类型(int/byte):

您可以改为使用该方法,因为它将为您执行以下操作:

[System.Management.Automation.LanguagePrimitives]::ConvertTo(Object, Type)
我将首先定义脚本块,然后单独调用它:

$a={ codehere }
& $a param1 param2
把这些都带上飞机:

$a={Param($t,$num);$num=[System.Management.Automation.LanguagePrimitives]::ConvertTo($num, $t);$num+2}
& $a byte 5
作为补充,它很好地解释了问题,并包含一个有限制的解决方案[1],具有替代解决方案:

隔离中使用的脚本块确实像匿名函数(它们也是脚本和命名函数的基础)。

虽然不可能使用非文字类型名称的强制转换/类型约束,但您可以使用
-as
运算符来实现类似效果

PS> & { param($t) $num = 10; $num+=2; $num -as $t } byte # !! use -as $t on OUTPUT
12  # type is [byte]
注意事项

PS> & { param($t) $num = 10; $num+=2; $num -as $t } byte # !! use -as $t on OUTPUT
12  # type is [byte]
  • 与PowerShell强制转换不同,
    -as
    运算符对某些类型敏感,但对其他类型不敏感:例如,它对
    [datetime]
    敏感,但对
    [double]
    不敏感

    • 这些有问题的不一致性将在中讨论
  • 如果无法进行转换,
    -as
    会安静地返回
    $null
    ,因此您可能必须显式处理该情况

  • 由于
    -as
    不能用于类型约束变量,因此后续操作可能会更改值的数据类型

    • 如果执行
      $num=10,则会发生这种情况-作为[byte]
      后跟
      $num+=2
      :添加将隐式地将类型更改为
      [int]
    • 因此,在输出上应用
      -as
      运算符,或在必要时在每个中间操作上应用。
      • 注意复合运算符,如
        +=
        ,其中
        -as
        无法按预期工作;例如,使用
        $num=($num+2)-as[byte]
        代替
        $num+=2-as[byte]
  • 顺便说一句:如果
    新变量
    支持类型约束,那么它将是一种替代方法,类似于
    新变量-type$t-Name num-Value 10
    ;它目前没有(从Windows PowerShell v5.1/PowerShell Core 6.1.0开始),但它可以


或者,使用
[scriptblock]::create()
从字符串表示创建脚本块,这允许您将类型名称“烘焙”到字符串中:

PS> & ([scriptblock]::Create('[{0}] $num=10; $num+=2; $num' -f 'byte'))
12  # type is [byte]
注意事项

  • 仅在您完全控制或信任其内容的字符串上使用此技术,因为可以通过这种方式构造任意命令

  • 此外,出于可维护性的考虑,此技术仅适用于小代码段


[1] 不完全等同于演员阵容,因为它不包括