PowerShell:打破嵌套循环

时间:2014-06-04 17:38:24

标签: loops powershell break

PowerShell中应该有一个break命令,可以通过分配标签来退出嵌套循环。只是它不起作用。这是我的代码:

$timestampServers = @(
    "http://timestamp.verisign.com/scripts/timstamp.dll",
    "http://timestamp.comodoca.com/authenticode",
    "http://timestamp.globalsign.com/scripts/timstamp.dll",
    "http://www.startssl.com/timestamp"
)

:outer for ($retry = 2; $retry -gt 0; $retry--)
{
    Write-Host retry $retry
    foreach ($timestampServer in $timestampServers)
    {
        Write-Host timestampServer $timestampServer
        & $signtoolBin sign /f $keyFile /p "$password" /t $timestampServer $file
        if ($?)
        {
            Write-Host OK
            break :outer
        }
    }
}
if ($retry -eq 0)
{
    WaitError "Digitally signing failed"
    exit 1
}

它打印以下内容:

retry 2
timestampServer http://timestamp.verisign.com/scripts/timstamp.dll
Done Adding Additional Store
Successfully signed and timestamped: C:\myfile.dll
OK
retry 1
timestampServer http://timestamp.verisign.com/scripts/timstamp.dll
Done Adding Additional Store
Successfully signed and timestamped: C:\myfile.dll
OK

ERROR: Digitally signing failed

我做错了什么?

请问我可以使用goto和标签吗?

使用Windows 7,我猜PS 2.0。该脚本至少应该在PS 2上运行。

2 个答案:

答案 0 :(得分:21)

使用带有循环标签的break时,不添加冒号。这一行:

break :outer

应该写成这样:

break outer

有关进一步演示,请考虑以下简单脚本:

:loop while ($true)
{
    while ($true)
    {
        break :loop
    }
}

执行时,它将永远运行而不会中断。但是这个脚本:

:loop while ($true)
{
    while ($true)
    {
        break loop
    }
}

应该退出,因为我将break :loop更改为break loop

答案 1 :(得分:1)

所以,我稍微更改了代码以使其清晰

$timestampServers = @(
    "http://timestamp.verisign.com/scripts/timstamp.dll",
    "http://timestamp.comodoca.com/authenticode",
    "http://timestamp.globalsign.com/scripts/timstamp.dll",
    "http://www.startssl.com/timestamp"
)


:outer for ($retry = 2; $retry -gt 0; $retry--)
{
    Write-Host retry $retry
    foreach ($timestampServer in $timestampServers)
    {
        Write-Host timestampServer $timestampServer
        #& $signtoolBin sign /f $keyFile /p "$password" /t $timestampServer $file

        if ($true)
        {

            break :outer
            Write-Host OK
        }
    }
}
if ($retry -eq 0)
{
    Write-Error "Digitally signing failed"  ## you have a typo there
    exit 1
}

这会产生以下结果:

retry 2
timestampServer http://timestamp.verisign.com/scripts/timstamp.dll
retry 1
timestampServer http://timestamp.verisign.com/scripts/timstamp.dll
C:\temp\t.ps1 : Digitally signing failed
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,t.ps1

所以,跳过Write-Host OK,但似乎还在继续循环。换句话说,它就像“继续”声明一样。

改变它就像提到删除':'的人一样,虽然PowerShell文档没有排除它:

 if ($true)
        {

            break outer
            Write-Host OK
        }

我得到了正确的行为。

retry 2
timestampServer http://timestamp.verisign.com/scripts/timstamp.dll

长话短说......不要使用':'