理解Powershell管道

网友投稿 1693 2022-09-16

理解Powershell管道

理解Powershell管道

深入理解管道

在我們前面的一些命令使用中可以看到,我們有使用管道 ​​|​​​ 來連接Cmdlet,可以看到管道可以帮助我们更好的完成工作,那么我们也应该深入的去了解一下它的原理,以便于我们后续使用中能更好的使用它,避免在出现问题的时候不知道怎么去解决,接下来我们一起看一下吧

Powershell如何传递数据给管道

当两条命令串联在一起时,Powershell必须搞清楚怎样将第一条命令的输出作为第二条命令的输入 示例 我们在文本中输入一些文本

# 写入一些文本Add-Content -Path 'D:\amos.txt' -Value WManSvc,AVS-17053-45304,AVS-17053-45304# 运行下面的命令Get-Content -Path 'D:\amos.txt' | Get-Service

当运行​Get-content​命令时,他会将文本文件中的计算机名称放入管道中。之后Powershell再决定如何将该数据传递给​Get-Service​命令,但Powershell一次只能使用单个参数接收传入数据。也就是说。Powershell必须决定由​Get-Service​的那个参数接收​Get-content​的输出结果。这个决定过程就成为管道参数绑定(Pipeline parameter binding)

方案A:使用ByPropertyname进行管道输入

当使用ByPropertyname这种方式实现管道参数绑定时,Powershell会确认命令A产生的数据对象类型,然后查看B中有哪个参数可以接收经由管道传过来对象的类型。我们可以使用​​Get-Content -Path d:\amos.txt | gm​​​ 和 ​​help Get-Service  -Full ​​  进行查看。

可以看到​​Get-Content -Path d:\amos.txt​​命令产生的对象类型是​System.String​,通过查询帮助信息,可以看到​Get-Service​中有存在可以从ByPropertyname管道中接收String类型的参数。检查发现,可以接收String类型数据的参数是-Name,查看帮忙信息,其说明是“指定要检索的服务名称”。因为第一个字段我设置的是一个服务名称,所以查询第一个字符串的时候Powershell可以正确的输出,后面两个报错很明显是告诉我们找不到这个服务名称。

Powershell只允许使用一个参数接收ByPropertyname管道返回的对象类型,那也就意味着,由于-Name参数接收了来自ByPropertyname管道返回的String类型数据,那么其它参数就没有办法再接收该数据了。

其实在这里​​help Get-Service  -Full​​进行查看可以看到所有参数的一些信息,每个参数是做什么的,是否接收管道输入等信息,如果不会使用命令的话可以多使用帮助命令来理解。

示例1

notepad.exeGet-Process -Name notepad | Get-Memberhelp Stop-Process -FullGet-Process -Name notepad | Stop-Process

我们首先开启了一个记事本的进程,我们在执行​​Get-Process -Name notepad | Stop-Process​​时,Stop-Process命令会使用-InputObject参数来接收这些来自ByValue管道的进程对象。这是诠释管道参数绑定一个比较恰当的示例,同时也反映了Powershell中比较重要的一个知识点:大部分情况下,使用相同名称的命令都可以使用ByValue方式互相之间进行管道传输。

方案B:使用ByValue进行管道输入

示例2

Get-Service -Name * | Get-MemberGet-Service -Name * | Stop-Process

我们可以看到​Get-Service​返回的是System.ServiceProcess.ServiceController类型的对象,但是我们查遍Stop-Process没有一个参数接收System.ServiceProcess.ServiceController类型对象,这也就意味着使用ByValue方式进行处理的方案失败了,此时Powershell会尝试使用其它备选方案ByPropertyName。

使用该方案同样需要将命令A的输出结果传递给命令B的参数。但是ByPropertyName与ByValue稍有不同。很多人都会认为这里的原理很复杂,其实Shell对该功能的实现其实非常简单:仅仅是孕照能够匹配参数名称的属性名称。在本例中属性“Name”与参数名称“-Name”相同,Shell会尝试将这两个值进行关联。

过程的大致是这样,首先,他会检查-Name参数是否可以接收来自ByPropertyName管道的输出。在该示例中,-Name参数可以接收来自ByPropertyName管道输出结果,所以这个连接可以正常工作。与ByValue管道只能使用一个参数不同,ByPropertyName会将每个匹配的属性与参数进行关联。在这个示例中,只有Name属性与-Name参数匹配。

示例3

# 用记事本新建下面一个文件 Alias.CSVName,Valued,Get-childitemsel,select-objectgo,invoke-commandimport-csv d:\Alias.csv

我們可以看到CSV文件中的列名称成为属性,而CSV中每一行的值成为一个对象。现在我们可以使用New-Alias进行接收数据,我们可以先看下 New-Alias是否支持参数进行接收,我們可以看到两个参数都可接收管道输入,在执行后我们可以看到新增加了三个别名

Import-Csv D:\Alias.csv | New-Alias

基本上管道在这里我们就能有个大概的认识了,这些内容我都是从书中 Windows PowerShell实战指南 第3版 中学习到的,这里的内容大部分都是从书中看到自己实践一遍来的。如果大家对Powershell有兴趣的话,可以购买图书自己看。虽然现在网络上有很多学习教程,但是有时候我还是认为看书更能静下心来学习,当然每个人的学习方法不一样,请根据自己的方式来学习吧。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:如何实现小程序跳转APP?(小程序与APP跳转逻辑关系与实现方式)
下一篇:svn执行clean up命令时报错
相关文章

 发表评论

暂时没有评论,来抢沙发吧~