Это, кстати, называется прокруткой экрана. Библиотека, которую я использовал для этого, - Простой HTML-парсер (/ g0).
Format-Table
не имеет ничего общего с тем, что я просто попробую сделать следующее в PowerSell V 4.0 и PowerShel V5.0, и проблема может быть воспроизведена:
Get-Process |Select-Object -Property name ; pause
арка поворота:
Get-Process |Select-Object -Property Name |%{Write-host $_.name};pause
Здесь снова выполняется пауза:
Get-Process |%{$_.name | Set-Content 'c:\temp\test.txt';$_} |Select-Object -Property Name ;pause
Но не здесь
Get-Process |%{$_.name | Set-Content 'c:\temp\test.txt';Start-Sleep -Milliseconds 1;$_} |Select-Object
-Property Name ;pause
Для меня в PowerShell V5.0 все работает, как если бы хост не нужен в инструкциях, которые конвейерны, тогда эти инструкции запускаются асинхронно.
Мне бы хотелось, чтобы люди, как @Keith Hill, смотрели на это поведение.
Что вы видите, это последствия новой функции PowerShell v5. Format-Table
теперь собирают ввод в течение 300 миллисекунд, чтобы найти лучшую ширину столбца. Он работает таким образом, даже если вы явно указали -AutoSize:$false
.
Когда вы вводите команду в командной строке, эта команда неявно передается в один экземпляр команды Out-Default
. Затем команда Out-Default
определяет, как форматировать объекты и печатать их на хосте (консоли) PowerShell. Таким образом, даже если вы не используете Format-Table
непосредственно в своем коде, это не означает, что у вас нет Format-Table
в вашем конвейере. Out-Default
может решить форматировать объекты как таблицу и использовать Format-Table
внутренне.
Пользовательские объекты с четырьмя или менее свойствами и без специального форматирования, определенные для них в файлах формата, отформатированы как таблица. Используя Select-Object
с двумя свойствами, вы создаете именно эти объекты.
Конвейер PowerShell является однопоточным. Это означает, что Format-Table
не может просто выводить все собранные объекты, когда прошло интервал в 300 миллисекунд. Format-Table
должны ждать, пока вы не нанесете на него следующий элемент (вызванный процесс) или конец сообщенного конвейера (вызванный конечный блок).
PS> Get-NetAdapter | Select-Object Name,Status
>>> Pause
>>> [PSCustomObject]@{Name='Some long name';Status='Some long status'} #1
>>> Pause
>>> [PSCustomObject]@{Name='Even longer name';Status='Even longer status'}
>>> Pause
Press Enter to continue...:
Name Status
---- ------
Ethernet Up
Some long name Some long status
Press Enter to continue...:
Even longer... Even longer s...
Press Enter to continue...:
PS>
Неявный Format-Table
ничего не печатает (строго говоря он печатает пустую строку) перед первым Pause
, потому что он все еще ждет больше входных объектов (еще 300 миллисекунд), чтобы определить ширину столбца. Когда первый объект (# 1) приходит через интервал 300 миллисекунд (при условии, что вы не должны нажимать клавишу Enter), тогда Format-Table
выбирает ширину столбца и печатает все собранные объекты. Любые другие объекты будут напечатаны без задержки, но они больше не могут влиять на ширину столбца. Если значение является большим для столбца, оно будет усечено.
PS> Get-NetAdapter | Select-Object Name,Status | Format-Table
>>> Pause
Name Status
---- ------
Ethernet Up
Press Enter to continue...:
PS>
С помощью этого кода до Format-Table
будет выполнен конечный блок явного Format-Table
. В конце блока Format-Table
известно, что он уже получил все входные данные, поэтому он может выбирать ширину столбца и сразу выводить все собранные объекты. Неявные Out-Default
видят, что объекты форматирования из выхода Format-Table
и Out-Default
знают, что им не требуется форматирование добавок и их печать на хосте (консоли) сразу же. Итак, вся таблица была напечатана до Pause
.
Обратите внимание на разницу в размещении конца метки таблицы (две пустые строки). В первом примере он помещается после последнего Pause
. Это потому, что неявный Format-Table
все еще активен и все еще ждет, что вы передаете ему дополнительный объект. Только когда ваша команда полностью завершена Format-Table
, подтвердите завершение ввода и вывода конца таблицы. Во втором примере явная Format-Table
завершается до Pause
, поэтому вся таблица (включая конец таблицы) печатается перед командой Pause
.
Разница в размещении конца метки таблицы может быть заметил и предыдущие версии PowerShell.