Windows Powershell使用管道
管道并不是什么新事物,以前的Cmd控制台也有重定向的命令,例如Dir|More可以将结果分屏显示。
传统的Cmd管道是基于文本的,但是Powershell是基于对象。
PS>ls|Sort-Object-DescendingName|Select-ObjectName,Length,LastWriteTime|ConvertTo-Html|Out-Filels.html PS>Get-Content.ls.html
NameLengthLastWriteTime test.vbs1702011/11/2816:42:03 test.txt2422011/11/2317:37:37 test.ps11402011/12/218:47:35 psdrive.html25562011/11/3016:04:00 Powershell_Cmdlets.html7358922011/11/2417:44:37 ping.bat632011/11/2815:30:04 name.html74202011/11/2417:37:28 myscript2011/11/2918:21:28 ls.html4342011/12/1411:22:30 LogoTestConfig.xml1862011/11/2811:12:08 function.ps1214662011/11/2919:23:58 employee.xml5562011/11/2511:20:33 d.txt02011/11/2317:25:23 c.txt02011/11/2317:25:23 b.txt02011/11/2317:25:23 alias.ps1120602011/11/2420:27:24 alias120602011/11/2420:26:36 ABC2011/11/2317:25:53 a.txt263842011/11/2420:04:31 a.html675802011/11/2418:30:13
首先列出当前目录下的目录和文件,然后根据文件名降序排列,再投影文件名,文件大小,文件的修改时间,转换成Html格式,输出到当前目录的ls.html
面向对象的管道
上面的例子属于面向对象的管道,每个命令的末尾可以使用新的命令对上个命令的结果做进一步处理,除非管道是以输出命令结束的。就像Sort-Object一样,对文件的列表进行排序,需要告诉它排序的关键字,按照升序还是降序。ls的返回值为一个数组,数组中的每一个元素都是一个对象,对象的每一个属性都可以作为Sort-Object的排序关键字。但是排序时必须指定一个具体的关键字,因为Powershell所传递的对象可能有很多属性。不像普通的文本,对象的信息都是结构化的,因此也使得Powershell的管道变得更加强大和方便。
转换命令执行的结果为文本
在执行Powershell命令时,解释器会默认在命令的结尾追加一个管道命令,Out-Default,这样可以将原来的对象结果以文本的形式显示在控制台上,但是并没有将结果进行转换,所以可以继续使用其它管道对对象的结果进行操作,但是一旦使用了诸如ConvertTo-Html这样的命令后,就会将结果转换成固定格式的纯文本。
常用的对管道结果进一步处理的命令有:
Compare-Object:比较两组对象。
ConvertTo-Html:将Microsoft.NETFramework对象转换为可在Web浏览器中显示的HTML。
Export-Clixml:创建对象的基于XML的表示形式并将其存储在文件中。
Export-Csv:将Microsoft.NETFramework对象转换为一系列以逗号分隔的、长度可变的(CSV)字符串,并将这些字符串保存到
一个CSV文件中。
ForEach-Object:针对每一组输入对象执行操作。
Format-List:将输出的格式设置为属性列表,其中每个属性均各占一行显示。
Format-Table:将输出的格式设置为表。
Format-Wide:将对象的格式设置为只能显示每个对象的一个属性的宽表。
Get-Unique:从排序列表返回唯一项目。
Group-Object:指定的属性包含相同值的组对象。
Import-Clixml:导入CLIXML文件,并在WindowsPowerShell中创建相应的对象。
Measure-Object:计算对象的数字属性以及字符串对象(如文本文件)中的字符数、单词数和行数。
more:对结果分屏显示。
Out-File:将输出发送到文件。
Out-Null:删除输出,不将其发送到控制台。
Out-Printer:将输出发送到打印机。
Out-String:将对象作为一列字符串发送到主机。
Select-Object:选择一个对象或一组对象的指定属性。它还可以从对象的数组中选择唯一对象,也可以从对象数组的开头或末尾选
择指定个数的对象。
Sort-Object:按属性值对象进行排序。
Tee-Object:将命令输出保存在文件或变量中,并将其显示在控制台中。
Where-Object:创建控制哪些对象沿着命令管道传递的筛选器。
管道的处理模式
当我们把许多命名组合成一个管道时,可能会感兴趣每一个命令的执行时是顺序执行还是同时执行?通过管道处理结果实际上是实时的。这就是为什么存在两个管道模式:
顺序模式(较慢):在顺序模式中管道中同一时间只执行一条命令,只有当前一条命令的所有执行完毕,才会把所有结果交付给下一条命令。这种模式速度慢并且耗内存,因为必须需要很多次分配空间存储中间结果。
流模式(较快):流模式会立即执行所有命令,同一时间可能在执行多条命令。前一条命令可能会产生多个结果,但是一旦产生其中一个结果,就会立即交付给下一条命令处理。这样的流模式节省比较节省内存,可能管道的某个任务还在执行,但是已经有部分结果输出了。减少了中间结果的保存。
管道命令的阻塞
可以使用Sort-Object对管道的结果进行排序,但是有时候排序可能导致整个操作系统阻塞,因为排序命令的的执行属于顺序模式,必须得上一条命令的结果全部完成,才能排序。
因此在使用这类命令时,要注意操作对象的大小,和它们需要的内存。例如这条命令:
DirC:-recurse|Sort-Object
-recurse选项是递归查询子目录,可想而知系统盘的文件和目录有多大。这条命令一旦运行起来,需要等很长很长的时间,甚至可能导致系统崩溃,得重启电脑。你可以在执行这条命令时,打开任务管理器查看Powershell进程的内存占用在以每秒种几十兆的速率增加。
到底哪些命令可能系统阻塞,要视命令的实现方式以及处理的对象大小决定,例如Sort-object导致阻塞的原因肯定是由于技术实现上采用的是内排序,没有使用外排序。但是象Out-Host-paging这样的命令属于流出来模式,就一般不会导致系统阻塞。