PowerShell 是否会根据需要自动将管道对象转换为字符串?
Does PowerShell automatically convert pipeline objects to strings as needed?
Split-Path
的帮助指出参数 -LiteralPath
和 -Leaf
不兼容:
SYNTAX
Split-Path [-Path] <System.String[]> -Leaf [-Resolve] # ...
Split-Path -LiteralPath <System.String[]> [-Resolve] # ...
此命令失败确认:
Split-Path -LiteralPath 'C:\foo.txt' -Leaf
# Split-Path: Parameter set cannot be resolved using the specified named parameters.
# One or more parameters issued cannot be used together
然而,管道工作得很好:
Get-Item 'C:\foo.txt' | Split-Path -Leaf
这是为什么?
我认为 Split-Path
会从管道接收一个对象并尝试将该对象的 PSPath
属性 绑定到它的 -LiteralPath
参数(别名:PSPath
),正如所解释的 .
我想因为我提供了 -Leaf
开关,参数绑定器知道使用包含 -Leaf
的参数集,这使 -LiteralPath
不在画面中。但是 PSPath
最终如何绑定到 -Path
?活页夹是否自动在对象上调用 .ToString()
以获取字符串形式的路径,然后它可以通过值 而不是 [=43= 绑定到 -Path
]经过
属性名字?它怎么知道要这样做?
我尝试使用 Trace-Command,但无法理解输出。
Trace-Command ParameterBinding { Get-Item 'C:\foo.txt' | Split-Path -Leaf } -PSHost
在使用 -Leaf
时遵循 Trace-Command
的输出(此处删减):
# First, powershell binds any manually specified args (-Leaf):
BIND NAMED cmd line args [Split-Path]
BIND arg [True] to param [Leaf] SUCCESSFUL
# Then it checks for required positional args
BIND POSITIONAL cmd line args [Split-Path]
BIND cmd line args to DYNAMIC parameters.
MANDATORY PARAMETER CHECK on cmdlet [Split-Path]
# Because -Leaf was specified, it knows only -Path is required, and tries to bind the object first:
BIND PIPELINE object to parameters: [Split-Path]
PIPELINE object TYPE = [System.IO.FileInfo]
BIND arg [C:\foo] to parameter [Path]
BIND arg [C:\foo] to param [Path] SKIPPED ## fails
# It tries again later on by coercing to string and succeeds:
Parameter [Path] PIPELINE INPUT ValueFromPipeline WITH COERCION
BIND arg [C:\foo] to parameter [Path]
COERCE arg to [System.String[]]
BIND arg [System.String[]] to param [Path] SUCCESSFUL
根据跟踪输出,powershell 尝试按 named args
> pipeline, no coercion
> pipeline, with coercion
的顺序使用。它会按照它们定义的顺序尝试每个可能的参数集。您可以按 (Get-Command Split-Path).Definition
.
的顺序列出参数集
没有 -Leaf
,它可以先使用没有强制转换的-LiteralPath
参数集,所以这就是运行。
和-Leaf
,排除了-LiteralPath
参数集,终于可以用-Path
了将管道对象强制转换为字符串。
Split-Path
的帮助指出参数 -LiteralPath
和 -Leaf
不兼容:
SYNTAX
Split-Path [-Path] <System.String[]> -Leaf [-Resolve] # ...
Split-Path -LiteralPath <System.String[]> [-Resolve] # ...
此命令失败确认:
Split-Path -LiteralPath 'C:\foo.txt' -Leaf
# Split-Path: Parameter set cannot be resolved using the specified named parameters.
# One or more parameters issued cannot be used together
然而,管道工作得很好:
Get-Item 'C:\foo.txt' | Split-Path -Leaf
这是为什么?
我认为 Split-Path
会从管道接收一个对象并尝试将该对象的 PSPath
属性 绑定到它的 -LiteralPath
参数(别名:PSPath
),正如所解释的
我想因为我提供了 -Leaf
开关,参数绑定器知道使用包含 -Leaf
的参数集,这使 -LiteralPath
不在画面中。但是 PSPath
最终如何绑定到 -Path
?活页夹是否自动在对象上调用 .ToString()
以获取字符串形式的路径,然后它可以通过值 而不是 [=43= 绑定到 -Path
]经过
属性名字?它怎么知道要这样做?
我尝试使用 Trace-Command,但无法理解输出。
Trace-Command ParameterBinding { Get-Item 'C:\foo.txt' | Split-Path -Leaf } -PSHost
在使用 -Leaf
时遵循 Trace-Command
的输出(此处删减):
# First, powershell binds any manually specified args (-Leaf):
BIND NAMED cmd line args [Split-Path]
BIND arg [True] to param [Leaf] SUCCESSFUL
# Then it checks for required positional args
BIND POSITIONAL cmd line args [Split-Path]
BIND cmd line args to DYNAMIC parameters.
MANDATORY PARAMETER CHECK on cmdlet [Split-Path]
# Because -Leaf was specified, it knows only -Path is required, and tries to bind the object first:
BIND PIPELINE object to parameters: [Split-Path]
PIPELINE object TYPE = [System.IO.FileInfo]
BIND arg [C:\foo] to parameter [Path]
BIND arg [C:\foo] to param [Path] SKIPPED ## fails
# It tries again later on by coercing to string and succeeds:
Parameter [Path] PIPELINE INPUT ValueFromPipeline WITH COERCION
BIND arg [C:\foo] to parameter [Path]
COERCE arg to [System.String[]]
BIND arg [System.String[]] to param [Path] SUCCESSFUL
根据跟踪输出,powershell 尝试按 named args
> pipeline, no coercion
> pipeline, with coercion
的顺序使用。它会按照它们定义的顺序尝试每个可能的参数集。您可以按 (Get-Command Split-Path).Definition
.
没有
-Leaf
,它可以先使用没有强制转换的-LiteralPath
参数集,所以这就是运行。和
-Leaf
,排除了-LiteralPath
参数集,终于可以用-Path
了将管道对象强制转换为字符串。