2016-01-17 3 views
8

В некоторых случаях, если я пытаюсь сделать паузу или сплю после команды Select-Object, произойдет пауза/сон до.Невозможно приостановить или спящий режим после выбора объекта

Например, с

Get-NetAdapter | Select-Object Name,Status 
Pause 

или

Get-NetAdapter | Select-Object Name,Status | Where-Object {$_ -ne $null} 
Pause 

выход находится:

Press Enter to continue...: 

Name  Status 
----  ------ 
Wi-Fi Up 
Ethernet Disconnected

В то время как с

Get-NetAdapter | Select-Object Name,Status | Format-Table 
Pause 

выход:

Name  Status 
----  ------ 
Wi-Fi Up 
Ethernet Disconnected 

Press Enter to continue...:

Что здесь происходит? Это ошибка или функция?

+0

Вы используете PowerShell v5? Возможно, это проблема. Https://connect.microsoft.com/PowerShell/Feedback/Details/1635172 Предлагается обходной путь с «Out-Host». –

+0

'pause' использует' Read-Host', см. 'Get-Command pause | Format-List' –

+5

Это новая функция 'Format-Table' в v5. 'Format-Table' собирает ввод в течение 300 миллисекунд (чтобы найти лучшую ширину столбца), прежде чем начинать выводить его. – PetSerAl

ответ

1

Format-Table не имеет ничего общего с этим я просто попробовать следующее в PowerSell V 4,0 и PowerShel V5.0 и проблема может быть воспроизведена:

Get-Process |Select-Object -Property name ; pause 

поворот Arround является:

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 все работает, как если хост не требуется в инструкции, которые конвейерная тогда эти инструкции выполняются asynchronosly.

Мне бы хотелось, чтобы люди, как @Keith Hill, смотрели на это поведение.

+1

Все неявно передано в 'Out-Default', поэтому ваш первый код эквивалентен'. {Get-Process | Select-Object -Property name; пауза} | Out-default'. И 'Out-Default' решают использовать' Format-Table' для форматирования вывода. Таким образом, на самом деле у вас есть '. {Get-Process | Select-Object -Property name; пауза} | Format-Table'. Если вы измените 'Format-Table' на' Format-List' или явно установили ширину столбца 'Format-Table @ {e = 'Name'; w = 50}', то после вывода будет вызываться 'pause'. Если вы добавляете синхронизацию для каждого выходного объекта, то вы увидите, что запуск выводится через интервал 300 миллисекунд. – PetSerAl

+0

'. {1..20 | ForEach-Object {$ SW = [Diagnostics.Stopwatch] :: StartNew()} {Write-Host" Перед написанием '$ _' ($ ($ SW.ElapsedMilliseconds));; [ PSCustomObject] @ {Property = $ _}; Write-Host "После написания '$ _' ($ ($ SW.ElapsedMilliseconds))"; Start-Sleep -Milliseconds 20}} | Format-Table' – PetSerAl

+0

Ваш первый код не является cohérent с вашим предложением. Все неявно передано в «Out-Default», поэтому мой первый был бы кодом, эквивалентным '{Get-Process | Select-Object -Property name | Out-Default; пауза} '. Тогда вы можете найти в документации Microsoft, где написано, что out-default вызывает таблицу формата? Я могу прочитать: «Командлет Out-Default отправляет выходные данные в форматтера по умолчанию и командлет вывода по умолчанию». – JPBlanc

6

Что вы видите, это последствия новой функции 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 миллисекунд (при условии, что вы не должны нажимать , введите), затем Format-Table определите ширину столбца и распечатайте все собранные объекты. Любые другие объекты будут напечатаны без задержки, но они больше не могут влиять на ширину столбца. Если значение велико для столбца, оно будет усечено.

PS> Get-NetAdapter | Select-Object Name,Status | Format-Table 
>>> Pause 

Name  Status 
----  ------ 
Ethernet Up 


Press Enter to continue...: 
PS> 

С помощью этого кода, конечный блок явного Format-Table будет выполняться перед Pause. В конце блока Format-Table знают, что он уже получил все входные данные, поэтому он может выбирать ширину столбца и сразу выводить все собранные объекты. Неявные Out-Default видят, что форматирование объектов с Format-Table вывода и Out-Default знают, что им не нужно форматировать добавление и печатать их на хосте (консоли) сразу же. Итак, вся таблица была напечатана до вызова Pause.

Обратите внимание на разницу в размещении знака конца таблицы (две пустые строки). В первом примере он помещался после последнего Pause. Это потому, что неявный Format-Table все еще активен и все еще ждет, что вы передаете ему дополнительный объект. Только когда ваша команда полностью завершена Format-Table подтвердите конец ввода и вывод конца таблицы. Во втором примере явное Format-Table завершается до Pause, поэтому вся таблица (включая конец таблицы) была напечатана до команды Pause.

Разница в размещении конца табличной метки может быть замечена и в предыдущих версиях PowerShell.

+0

Простите, но то, что я не понимаю в вашей демонстрации, - это почему с явным форматированием? – JPBlanc

+0

@JPBlanc Я добавляю эту информацию в свой ответ. – PetSerAl

Смежные вопросы