我似乎遇到了一个奇怪的错误,或者我在我的剧本中遗漏了一些东西。
在我的脚本中,我正在使用虚假进度条功能显示进度。它的工作原理是重复更新控制台的同一行,模仿进度条。请参阅以下功能:
# 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。想法?
答案 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组合在一起,这样只有当缓冲区几乎已满时才会清除缓冲区的旧部分。