3 回答

TA貢獻1797條經(jīng)驗 獲得超6個贊
您看到的是新PowerShell v5功能的后果。Format-Table現(xiàn)在收集輸入300毫秒,以找到更好的列寬。即使您明確指定,它也會以這種方式工作-AutoSize:$false。
在命令提示符下鍵入command時,該命令隱式地通過管道傳遞給單個Out-Default命令實例。Out-Default然后,該命令決定如何格式化對象并在PowerShell主機(控制臺)上打印它們。因此,即使您沒有Format-Table直接在您的代碼中使用,這并不意味著您沒有Format-Table在您的管道中。Out-Default可以決定將對象格式化為表格并在Format-Table內(nèi)部使用。
具有四個或更少屬性且沒有在格式文件中為它們定義自定義格式的自定義對象被格式化為表格。通過使用Select-Object兩個屬性,您可以精確地生成該對象。
PowerShell管道是單線程的。這意味著Format-Table當300毫秒間隔過去時,不能只輸出所有收集的對象。Format-Table必須等到你管道下一個項目(調(diào)用進程塊)或報告管道結(jié)束(調(diào)用結(jié)束塊)。
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毫秒尚未過去)來決定列寬。當?shù)谝粋€對象(#1)在300毫秒間隔后出現(xiàn)(假設(shè)您不要在按下時禁用Enter),然后Format-Table決定列寬并打印所有收集的對象。將立即打印任何其他對象,但它們不再影響列寬。如果列的值很大,則會被截斷。
PS> Get-NetAdapter | Select-Object Name,Status | Format-Table
>>> Pause
Name Status
---- ------
Ethernet Up
Press Enter to continue...:
PS>
使用此代碼,F(xiàn)ormat-Table將在之前執(zhí)行顯式結(jié)束塊Pause。在結(jié)束塊中,F(xiàn)ormat-Table知道它已經(jīng)獲得了所有輸入,因此它可以決定列寬并立即輸出所有收集的對象。隱式Out-Default看到從Format-Table輸出格式化對象,并Out-Default知道它們不需要任何添加格式并立即在主機(控制臺)上打印它們。所以在Pause調(diào)用之前打印整個表。
注意表格標記結(jié)尾的位置差異(兩個空行)。在第一個例子中,它放在最后Pause。這是因為隱式Format-Table仍處于活動狀態(tài)并仍在等待,您將其他對象傳遞給它。只有當您的命令完全完成時,F(xiàn)ormat-Table才會確認表標記的輸入和輸出結(jié)束。在第二個例子中,顯式Format-Table完成之前Pause,所以在Pause命令之前打印整個表(包括表標記的結(jié)尾)。
表標記結(jié)尾的位置差異也可以在PowerShell的早期版本中注意到。

TA貢獻1864條經(jīng)驗 獲得超2個贊
Format-Table
與此無關(guān)我只是在PowerSell V 4.0和PowerShel V5.0中嘗試以下內(nèi)容并且可以重現(xiàn)該問題:
Get-Process |Select-Object -Property name ; pause
轉(zhuǎn)彎是:
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中,一切都像在流水線操作的指令中不需要主機一樣,然后這些指令以異步方式運行。

TA貢獻1777條經(jīng)驗 獲得超10個贊
一切都隱含地用管道輸送Out-Default
,所以你的第一個代碼相當于.{Get-Process |Select-Object -Property name ; pause}|Out-Default
。并Out-Default
決定使用Format-Table
格式化輸出。所以事實上你有.{Get-Process |Select-Object -Property name ; pause}|Format-Table
。如果更改Format-Table
為Format-List
或明確設(shè)置列寬Format-Table @{e='Name';w=50}
,則pause
在輸出后將調(diào)用。如果在每個輸出對象上添加時序,那么您將看到,在300毫秒間隔后開始輸出。