PowerShell脚本在100多行输出后开始添加空行?

时间:2013-08-21 15:20:02

标签: powershell

我似乎遇到了一个奇怪的错误,或者我在我的剧本中遗漏了一些东西。

在我的脚本中,我正在使用虚假进度条功能显示进度。它的工作原理是重复更新控制台的同一行,模仿进度条。请参阅以下功能:

# Update-Progress-Bar : v1.0 : 2013-07-29
# Displays a percentage bar. Meant to be used repeatedly to update the same console line (giving the appearance of incrementing progress).
# - $Percentage : Determines how much progress is shown on the bar.
# - $Message : The message that accompanies the progress bar.
function Update-Progress-Bar ($Percentage, $Message){
    # Save the current cursor position so we can come back later.
    $CursorPosition = $Host.UI.RawUI.CursorPosition

    # Convert the percentage into a proper progress bar.
    $ProgressBarMax = "20"
    $ProgressBarCount = [Math]::Floor([Decimal]($Percentage / 5))
    $ProgressBar = ("#" * $ProgressBarCount) + (" " * ($ProgressBarMax - $ProgressBarCount))

    # Change the format of the percentage depending on length.
    switch ($Percentage.Length){
        1 {$Percentage = "  " + $Percentage + "%"}
        2 {$Percentage = " " + $Percentage + "%"}
        default {$Percentage = $Percentage + "%"}
    }

    # Trim or pad the message as necessary.
    $MessageMaxLength = "50"
    if ($Message.Length -gt $MessageMaxLength){ $Message = $Message.Remove($MessageMaxLength) }
    else { $Message = $Message + (" " * ($MessageMaxLength - $Message.Length)) }    

    # Display our progress bar, percentage, and message.
    Write-Host -nonewline -ForeGroundColor Blue "[$ProgressBar] $Percentage"
    Write-Host " | $Message"

    # Revert back to the original cursor position.
    $Host.UI.RawUI.CursorPosition = $CursorPosition
}

无论出于何种原因,在为大约100多条记录工作之后(我将其作为脚本的一部分,我经常对1000台机器执行操作),它开始执行双线换行,这会破坏功能进度条。所以我最终得到了......

[ 126 / 2275 ] ComputerName1
[                    ]   0% | Verifying network connectivity...

[##                  ]  10% | Verifying file system access...

[####                ]  20% | Determining installed operating system...

[######              ]  30% | Executing action...

[####################] 100% | Action Completed



[ 127 / 2275 ] ComputerName2
[                    ]   0% | Verifying network connectivity...

[##                  ]  10% | Verifying file system access...

[####                ]  20% | Determining installed operating system...

[######              ]  30% | Executing action...

[####################] 100% | Action Completed

什么时候应该......

[ 126 / 2275 ] ComputerName1
[####################] 100% | Action Completed

[ 127 / 2275 ] ComputerName2
[####################] 100% | Action Completed

对此问题的任何想法和可能的解决方法?

编辑#1:当我达到控制台的缓冲区高度限制时,是否可能发生这种情况(例如,它开始丢弃旧的输出行)?

编辑#2:我已经确认,如果我增加控制台窗口的缓冲区宽度和高度,此问题就会消失。我仍然不确定如何解决这个bug。想法?

1 个答案:

答案 0 :(得分:0)

我在自己的机器上验证了这个错误。一旦开始包装缓冲区,-nonewline就无法完成其任务。

您可以做一些解决方法:

1)以编程方式将BufferSize增加到固定大小

$Host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(120, 5000)

2)每隔一段时间清除屏幕,可能每100个节点或每个节点之后如果你不需要关注输出

3)仅在您接近缓冲限制时清除屏幕

if($Host.UI.RawUI.CursorPosition.Y -gt ($Host.UI.RawUI.BufferSize.Height - 5)) {cls}

4)通过暂时减小缓冲区的大小,仅清除屏幕缓冲区的旧部分。我使用了你的功能,没有动过(除了重命名以删除第二个" - ")。屏幕缓冲区为100时,奇数行为将从数字50开始(每个循环2条输出线)

49 / 2000
[####################] 100% | FINAL
50 / 2000
[####                ]  20% | First
[########            ]  40% | Second
[############        ]  60% | Third
[################    ]  80% | Fourth
[####################] 100% | FINAL

51 / 2000
[####                ]  20% | First
[########            ]  40% | Second
[############        ]  60% | Third
[################    ]  80% | Fourth
[####################] 100% | FINAL

但是通过BufferSize切换,我一直到2000/2000都没有任何障碍

1998 / 2000
[####################] 100% | FINAL
1999 / 2000
[####################] 100% | FINAL
2000 / 2000
[####################] 100% | FINAL

$range = 1..2000

以下测试代码:

foreach($i in $range)
{
    $Host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(120, 3000)

    Write-Host
    Write-Host $i "/ 2000"

    Update-ProgressBar "20" "First"
    Update-ProgressBar "40" "Second"
    Update-ProgressBar "60" "Third"
    Update-ProgressBar "80" "Fourth"
    Update-ProgressBar "100" "FINAL"

    $Host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(120, 2990)
}

实际上,您可以将3和4组合在一起,这样只有当缓冲区几乎已满时才会清除缓冲区的旧部分。