选择对象后无法暂停或睡眠 [英] Unable to Pause or Sleep after Select-Object
问题描述
在某些情况下,如果我尝试在 Select-Object
命令之后暂停或睡眠,则暂停/睡眠发生在之前命令.
In some cases, if I try to pause or sleep after a Select-Object
command, the pause/sleep occurs before the command.
例如,与
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...:
这是怎么回事?这是错误还是功能?
What's going on here? Is this a bug or a feature?
推荐答案
您看到的是新 PowerShell v5 功能的结果.Format-Table
现在收集 300 毫秒的输入以找到更好的列宽.即使您明确指定 -AutoSize:$false
,它也会以这种方式工作.
What you see is a consequences of new PowerShell v5 feature. Format-Table
now collect input for 300 milliseconds to find better column width. It work this way even if you explicitly specify -AutoSize:$false
.
当您在命令提示符中键入命令时,该命令会隐式地通过管道传输到 Out-Default
命令的单个实例.Out-Default
命令然后决定如何格式化对象并在 PowerShell 主机(控制台)上打印它们.因此,即使您不直接在代码中使用 Format-Table
,也不意味着您的管道中没有 Format-Table
.Out-Default
可以决定将对象格式化为表格并在内部使用 Format-Table
.
When you type command in command prompt, that command implicitly piped to single instance of Out-Default
command. The Out-Default
command then decide how to format objects and print them on PowerShell host (console). So that, even if you does not use Format-Table
directly in your code, that does not mean that you does not have Format-Table
in your pipeline. Out-Default
can decide to format objects as table and use Format-Table
internally.
具有四个或更少属性且未在格式文件中为其定义自定义格式的自定义对象被格式化为表格.通过使用带有两个属性的 Select-Object
,您可以准确地生成这些对象.
Custom objects with four or less properties and without custom formatting defined for them in format files are formatted as table. By using Select-Object
with two properties you produce exactly that objects.
PowerShell 管道是单线程的.这意味着 Format-Table
不能只在 300 毫秒间隔过去时输出所有收集的对象.Format-Table
必须等到你通过管道将下一个项目(进程块调用)或管道结束报告(结束块调用).
PowerShell pipeline is single-threaded. That means that Format-Table
can not just output all collected objects when 300 milliseconds interval elapsed. Format-Table
have to wait till you pipe next item to it (process block invoked) or end of pipeline reported (end block invoked).
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>
Implicit Format-Table
在第一次 Pause
之前不打印任何内容(严格说它打印空行),因为它仍在等待更多输入对象(300 毫秒尚未过去)) 来决定列宽.当第一个对象(#1)在 300 毫秒间隔后出现时(假设你不快速按下 Enter),然后 Format-Table
决定列宽并打印所有收集的对象.任何其他对象将立即打印,但它们不再影响列宽.如果列的值太大,它将被截断.
Implicit Format-Table
does not print anything (strictly saying it print empty line) before first Pause
because it still waiting for more input objects (300 milliseconds not yet elapsed) to decide on column width. When first object (#1) come after 300 milliseconds interval (assuming that you are not to fast on pressing Enter), then Format-Table
decide on column width and print all collected objects. Any further objects will be printed without delay, but them can not affect column width anymore. If value is to big for column it will be truncated.
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
调用之前就被打印出来了.
With this code, end block of explicit Format-Table
will be executed before Pause
. In end block Format-Table
know that it already got all the input, so it can decide on column width and output all collected objects right away. Implicit Out-Default
see that formatting objects from Format-Table
output, and Out-Default
know that them does not need any addition formatting and print them on host (console) right away as well. So whole table got printed before Pause
invoked.
注意表格结束标记(两个空行)位置的不同.在第一个示例中,它放在最后一个 Pause
之后.这是因为隐式 Format-Table
仍然处于活动状态并且仍在等待,您将其他对象传递给它.只有当你的命令完全完成 Format-Table
确认输入结束和表标记输出结束.在第二个示例中,显式 Format-Table
在 Pause
之前完成,因此在 Pause
命令之前打印整个表格(包括表格结束标记).
Notice the difference in placement of end of table mark (two empty lines). In first example it placed after last Pause
. It is because implicit Format-Table
still active and still wait, that you pass additional object to it. Only when your command fully completed Format-Table
acknowledge end of input and output end of table mark. In second example, explicit Format-Table
completes before Pause
, so whole table (including end of table mark) got printed before Pause
command.
表格结束标记位置的不同也可以在以前的 PowerShell 版本中注意到.
The difference in placement of end of table mark can be noticed it previous versions of PowerShell as well.
这篇关于选择对象后无法暂停或睡眠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!