gpt4 book ai didi

Powershell "Set-PSDebug -Trace 2"导致意外结果

转载 作者:行者123 更新时间:2023-12-04 12:48:06 27 4
gpt4 key购买 nike

我遇到了一个奇怪的问题,在设置“Set-PSDebug -Trace 2”时出现不同的行为。

我将其追溯到未正确执行的 switch 语句,并且能够在 Powershell V3 上重现它,但不能在 Powershell V2 或 Powershell V1 上重现(按预期工作)

取下面的简单函数:

function DoTest {
$result = "Switch Case Not Executed"
$VendorName = "Microsoft"
switch ($VendorName)
{
"Microsoft" { $result = "Switch Case Executed" }
}
Write-host "Switch: $($VendorName) -> $result"

}

现在运行以下命令:
#Works as expected
Set-PSDebug -Off; DoTest;

#Doesn't work as expected
Set-PSDebug -Trace 2; DoTest;

使用 PSDebug 跟踪在 PosH V3 上的结果
DEBUG:    3+ Set-PSDebug -Trace 2;  >>>> DoTest;
DEBUG: 1+ function DoTest >>>> {
DEBUG: ! CALL function 'DoTest'
DEBUG: 2+ >>>> $result = "Switch Case Not Executed"
DEBUG: ! SET $result = 'Switch Case Not Executed'.
DEBUG: 3+ >>>> $VendorName = "Microsoft"
DEBUG: ! SET $VendorName = 'Microsoft'.
DEBUG: ! SET $switch = 'Microsoft'.
DEBUG: 4+ switch ( >>>> $VendorName)
DEBUG: ! SET $switch = ''.
DEBUG: 9+ >>>> Write-host "Switch: $($VendorName) -> $result"
DEBUG: 9+ Write-host "Switch: $( >>>> $VendorName) -> $result"
Switch: Microsoft -> Switch Case Not Executed
DEBUG: 11+ >>>> }

在 PoSH 版本 3 中,即使是调试跟踪也表明该值已设置,但似乎完全跳过了 switch 语句。我什至尝试了 Set-StrictMode一切正常。只有当我启用 PSDebug 跟踪时。这种行为是有意的吗?

最佳答案

经过详尽的调查,这似乎是 Powershell 中的一个错误。 $switch变量在 Debug模式下被破坏,最终成为某种数组枚举器,在一个空数组或类似的东西上。我建议在 http://connect.microsoft.com 上提交问题

解决方法 1:

# Pro: No scoping differences between if statement blocks and function
# Con: big piles of If ... else if ... else if ... can get really annoying to code and maintain
# Con: Statements are limited to single execution, pipeline is lifted to function level instead of statement level
... same code as before but using an if instead of switch ...
if($VendorName = 'Microsoft') { $result = "Switch Case Executed" }
else { $result = "FAIL!" }

解决方法 2:
# Pro: Each script block is self-contained and has private scope
# Pro: "cases" can be added without modifying DoIt function, and even passed into the function
# Pro: "cases" can be used in a pipeline
# Con: Indirect script blocks can be difficult to understand at first
function DoTest {
$result = "Switch Case Not Executed"
$VendorName = "Microsoft"

$SwitchHack = @{
Microsoft = { "Microsoft Case Executed" }
Default = { "Default Case Executed" }
}

if($SwitchHack.Keys -contains $VendorName) {
$result = $SwitchHack."$VendorName".InvokeReturnAsIs()
} else {
$result = $SwitchHack.Default.InvokeReturnAsIs()
}

'Switch: {0} -> {1}' -f $VendorName, $result | Write-Host
}

Set-PSDebug -Trace 2
DoTest

因为我很无聊,所以我写了 Workaround 3,它只是 2 将 Switch 移到了一个函数
function Switch-Object {
param(
[Parameter(Mandatory=$true)]
[String]$In,
[Parameter(Mandatory=$true)]
[hashtable]$Actions
)

try {
$Actions."$In".InvokeReturnAsIs()
}
catch {
throw "Unknown Action Label"
}
}

function DoTest {
$result = "Switch Case Not Executed"
$VendorName = "Microsoft"

$VendorActions = @{
Microsoft = { "Microsoft Case Executed" }
}

$result = Switch-Object -On:$VendorName -Actions:$VendorActions
'Switch: {0} -> {1}' -f $VendorName, $result | Write-Host
}

Set-PSDebug -Trace 2
DoTest

关于Powershell "Set-PSDebug -Trace 2"导致意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18721593/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com