了解管道Understanding pipelines

本文内容

管道的行为就像一系列连接的管道段一样。沿着管道移动的项会通过每个管道段。若要在 PowerShell 中创建管道,请使用管道运算符“|”将命令连接在一起。每个命令的输出都将被用作下一命令的输入。

用于管道的符号类似于其他 shell 中使用的符号。初看起来 PowerShell 中管道的不同之处可能并不明显。尽管你会在屏幕上看到文本,但 PowerShell 通过管道在命令之间传递对象,而不是文本。

PowerShell 管道The PowerShell pipeline

管道可能是命令行界面中使用的最有价值的概念。如果使用得当,管道可以减少使用复杂命令的工作量,并且可以更轻松地查看命令的工作流程。管道中的每个命令(称为管道元素)将其输出逐项传递到管道中的下一个命令。命令不必一次处理多个项目。结果是减少了资源消耗,并且能够立即开始获取输出。

例如,如果使用 Out-Host cmdlet 来强制逐页显示来自于另一个命令的输出,那么这一输出看起来就像分页显示在屏幕上的普通文本:

1. Get-ChildItem -Path C:\WINDOWS\System32 | Out-Host -Paging
1. Directory: C:\WINDOWS\system32

3. Mode                LastWriteTime         Length Name
4. ----                -------------         ------ ----
5. d-----        4/12/2018   2:15 AM                0409
6. d-----        5/13/2018  11:31 PM                1033
7. d-----        4/11/2018   4:38 PM                AdvancedInstallers
8. d-----        5/13/2018  11:13 PM                af-ZA
9. d-----        5/13/2018  11:13 PM                am-et
10. d-----        4/11/2018   4:38 PM                AppLocker
11. d-----        5/13/2018  11:31 PM                appmgmt
12. d-----        7/11/2018   2:05 AM                appraiser
13. d---s-        4/12/2018   2:20 AM                AppV
14. d-----        5/13/2018  11:10 PM                ar-SA
15. d-----        5/13/2018  11:13 PM                as-IN
16. d-----        8/14/2018   9:03 PM                az-Latn-AZ
17. d-----        5/13/2018  11:13 PM                be-BY
18. d-----        5/13/2018  11:10 PM                BestPractices
19. d-----        5/13/2018  11:10 PM                bg-BG
20. d-----        5/13/2018  11:13 PM                bn-BD
21. d-----        5/13/2018  11:13 PM                bn-IN
22. d-----        8/14/2018   9:03 PM                Boot
23. d-----        8/14/2018   9:03 PM                bs-Latn-BA
24. d-----        4/11/2018   4:38 PM                Bthprops
25. d-----        4/12/2018   2:19 AM                ca-ES
26. d-----        8/14/2018   9:03 PM                ca-ES-valencia
27. d-----        5/13/2018  10:46 PM                CatRoot
28. d-----        8/23/2018   5:07 PM                catroot2
29. <SPACE> next page; <CR> next line; Q quit
30. ...

分页还会降低 CPU 利用率,因为准备好显示完整页面时,会转为处理 Out-Host cmdlet。管道中位于前面的 cmdlet 暂停执行,直到输出的下一页可用。

可以看到 Windows 任务管理器监视的 PowerShell 使用的 CPU 和内存存在差异。运行以下命令:Get-ChildItem C:\Windows -Recurse。将 CPU 和内存使用情况与此命令进行比较:Get-ChildItem C:\Windows -Recurse | Out-Host -Paging。

管道中的对象Objects in the pipeline

在 PowerShell 中运行 cmdlet 时,可以看到文本输出,因为必须在控制台窗口中以文本形式表示对象。文本输出可能不会显示输出的对象的所有属性。

例如,请考虑 Get-Location cmdlet。如果运行 Get-Location,而当前位置是 C 驱动器的根路径,将看到以下输出:

1. PS> Get-Location

3. Path
4. ----
5. C:\

文本输出是信息摘要,而非 Get-Location 返回的对象的完整表示形式。输出中的标题通过格式化屏幕显示数据的过程添加。

通过管道将输出传递到 Get-Member cmdlet 后,可以获取有关 Get-Location 返回的对象信息。

1. PS> Get-Location | Get-Member
1. TypeName: System.Management.Automation.PathInfo

3. Name         MemberType Definition
4. ----         ---------- ----------
5. Equals       Method     bool Equals(System.Object obj)
6. GetHashCode  Method     int GetHashCode()
7. GetType      Method     type GetType()
8. ToString     Method     string ToString()
9. Drive        Property   System.Management.Automation.PSDriveInfo Drive {get;}
10. Path         Property   string Path {get;}
11. Provider     Property   System.Management.Automation.ProviderInfo Provider {get;}
12. ProviderPath Property   string ProviderPath {get;}

Get-Location 返回 PathInfo 对象,其中包含当前路径和其他信息。