未定义的属性名称显示为有效

时间:2018-03-09 20:25:21

标签: powershell

以下两个命令产生不同的输出。

<form id="subscribe-form" class="footer-sign-up" action="/subscribe" method="POST">
    <input type="text" placeholder="First Name" name="first_name" id="fname" required>
    <input type="text" placeholder="Last Name" name="last_name" id="lname" required>
    <input id="footer-email" type="text" placeholder="Your Email Address" name="email" required>


    <button type="submit" id="subscribe" class="signupbtn">sign up</button>

</form>

Get-ChildItem | Sort-Object -Property Length Get-ChildItem | Sort-Object -Property Len 不是Len的成员。 PowerShell是否与System.IO.FileInfo成员匹配Len?如果没有,那么为什么没有错误消息说Length不是属性?

2 个答案:

答案 0 :(得分:2)

不,它不是System.IO.FileInfo的成员,您可以通过添加-Debug开关看到:

Get-ChildItem | Sort-Object -Property Len -Debug

输出如下:

DEBUG: "Sort-Object" - "Len" cannot be found in "InputObject".

我猜其原因是cmdlet的防御性实施:

  

如果一个对象没有指定的属性之一,那么   该对象的属性值由cmdlet解释为Null   并放置在排序顺序的末尾。

答案 1 :(得分:1)

使用更一般的信息补充Martin Brandl's helpful answer

虽然 PowerShell的弹性语法仅适用于参数名称 (例如,仅为{{指定-p 1}}),而不是(参数),你选项来完成

  • 编辑时间:使用标签完成

    • 这适用于命令行以及安装了PowerShell扩展的Visual Studio代码(您还可以获得 IntelliSense ),只要PowerShell可以静态使用推断输出类型 [1] 前一个管道段中的命令。
  • 运行时 -Property和其他几个cmdlet允许您使用通配符表达式来匹配属性名称

    Sort-Object

请注意,多个属性可能匹配,并且给定参数必须明确设计为支持通配符(与类似POSIX的shell不同,它不是不是解析通配符的PowerShell本身。)

直接访问对象 上的不存在的属性时,默认情况下不报告错误,并返回Get-ChildItem | Sort-Object -Property Len* # "Len*" matches "Length"

$null

相反,如果(Get-Item /).Foo # Outputs $null as the value of nonexistent property "Foo" 或更高版本生效,则会报告(语句终止)错误,但请注意 Set-StrictMode -Version 2 将属性名称作为参数 传递时应用,例如上面的Set-StrictMode

至于可能导致Sort-Object未强制执行指定属性的动机:

PowerShell允许您通过管道传递任何类型混合的对象作为输入,对象一次传递一个
(同样,PowerShell的默认数组类型为Sort-Object,允许您创建混合类型数组,例如[object[]]

即使有(可能)同类输入(例如1, 'hi', $True发出的[System.IO.FileInfo]个实例),接收命令也无法检测到预先的情况,因为它一次只能看到一个物体。

通常,cmdlet应该能够优雅地处理输入中的混合类型,并且将不存在的属性视为Get-ChildItem -File总体上是更好的选择,特别是考虑到:

  • 如果输入对象的至少子集具有感兴趣的属性,则cmdlet仍然可以在输入上有意义地行动(见下文)。

  • cmdlet无法事先知道 该子集是否为空。

异构输入的示例:

通过管道发送一组自定义对象,并按属性$null对其进行排序,其中一个对象缺少:

val

输出:

[pscustomobject] @{ n = 'o1'; val = 2 },
[pscustomobject] @{ n = 'o2' },
[pscustomobject] @{ n = 'o3'; val = 1 } | Sort-Object val

在所有具有n val - --- o3 1 o1 2 o2 属性的输入对象中执行了排序,而那些没有放置在 end 的输入对象,如{{马丁答案中的{1}}文档。

[1]所有内置cmdlet都应如此;要确保它与自定义函数一起使用,请使用.val属性定义它们 - 请参阅我的this answer了解更多信息。