gpt4 book ai didi

PowerShell 开始在文件路径前添加 Microsoft.PowerShell.Core\FileSystem::

转载 作者:行者123 更新时间:2023-12-05 02:08:28 29 4
gpt4 key购买 nike

我在 PowerShell 中遇到以下行为,我无法解释并且觉得很麻烦。

我在任意目录下工作,目录路径显示在提示中:

PS C:\Users\Rene\AppData\Local\Temp>

此外,get-location 报告“正确”路径:

PS C:\Users\Rene\AppData\Local\Temp> get-location

Path
----
C:\Users\Rene\AppData\Local\Temp

然后我输入mkdir xyz | cd 以创建一个目录并将工作目录更改为这个新目录:

PS C:\Users\Rene\AppData\Local\Temp> mkdir xyz | cd

突然,提示中的路径以 Microsoft.PowerShell.Core\FileSystem:: 为前缀:

PS Microsoft.PowerShell.Core\FileSystem::C:\Users\Rene\AppData\Local\Temp\xyz>

此更改也反射(reflect)在 get-location 中:

PS Microsoft.PowerShell.Core\FileSystem::C:\Users\Rene\AppData\Local\Temp\xyz> get-location

Path
----
Microsoft.PowerShell.Core\FileSystem::C:\Users\Rene\AppData\Local\Temp\xyz

这是怎么回事,我该如何关闭该前缀?

最佳答案

倒序:

How can I turn that prefix off?

很简单,使用显式管道绑定(bind)!

mkdir xyz |cd -Path {$_.FullName}

What is going on here?

好问题!您在这里看到的是提供程序 cmdlet(Get-ChildItemGet-ItemSet-Location 等)实现管道绑定(bind)

当您针对 FileSystem 提供程序调用 New-Item(mkdir 所做的)时,它会返回一个对象(对应于新创建的文件或目录)有一堆隐藏属性,PowerShell 使用这些隐藏属性跨提供者跟踪项目 - 这些可以通过 Get-Member -Force 发现:

PS C:\> Get-Item .|Get-Member PS* -MemberType NoteProperty -Force


TypeName: System.IO.DirectoryInfo

Name MemberType Definition
---- ---------- ----------
PSChildName NoteProperty string PSChildName=C:\
PSDrive NoteProperty PSDriveInfo PSDrive=C
PSIsContainer NoteProperty bool PSIsContainer=True
PSParentPath NoteProperty string PSParentPath=
PSPath NoteProperty string PSPath=Microsoft.PowerShell.Core\FileSystem::C:\
PSProvider NoteProperty ProviderInfo PSProvider=Microsoft.PowerShell.Core\FileSystem

当您使用下游提供程序 cmdlet(例如 Set-Location/cd)构建管道语句时,它使用提供程序限定的 PSPath 值来绑定(bind)输入对象。

这可以通过 Trace-Command 观察到:

PS C:\> Trace-Command -Expression {Get-Item .|Set-Location} -Name ParameterBinding,MemberResolution -PSHost

这导致(为简洁起见,我删除了 Get-Item 的详细信息):

DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Set-Location]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Set-Location]
DEBUG: ParameterBinding Information: 0 : BIND cmd line args to DYNAMIC parameters.
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Set-Location]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Set-Location]
DEBUG: ParameterBinding Information: 0 : PIPELINE object TYPE = [System.IO.DirectoryInfo]
DEBUG: ParameterBinding Information: 0 : RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 : Parameter [Path] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\\] to parameter [Path]
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\\] to param [Path] SKIPPED
DEBUG: ParameterBinding Information: 0 : Parameter [Path] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
DEBUG: MemberResolution Information: 0 : Lookup
DEBUG: MemberResolution Information: 0 : "Path" NOT present in type table.
DEBUG: MemberResolution Information: 0 : Adapted member: not found.
DEBUG: ParameterBinding Information: 0 : Parameter [StackName] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
DEBUG: MemberResolution Information: 0 : Lookup
DEBUG: MemberResolution Information: 0 : "StackName" NOT present in type table.
DEBUG: MemberResolution Information: 0 : Adapted member: not found.
DEBUG: ParameterBinding Information: 0 : Parameter [LiteralPath] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
DEBUG: MemberResolution Information: 0 : Lookup
DEBUG: MemberResolution Information: 0 : "LiteralPath" NOT present in type table.
DEBUG: MemberResolution Information: 0 : Adapted member: not found.
DEBUG: MemberResolution Information: 0 : Lookup
DEBUG: MemberResolution Information: 0 : Found PSObject instance member: PSPath.
DEBUG: ParameterBinding Information: 0 : BIND arg [Microsoft.PowerShell.Core\FileSystem::C:\] to parameter [LiteralPath]
DEBUG: ParameterBinding Information: 0 : BIND arg [Microsoft.PowerShell.Core\FileSystem::C:\] to param [LiteralPath] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Set-Location]
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing

如您所见,PowerShell 放弃将 C:\ 绑定(bind)到 Set-Location-Path 参数,以某种方式绑定(bind) PSPath属性值改为-LiteralPath更合适?!

原因是 -LiteralPath 参数是 PSPath 的别名,通过使用 Get-Command 挖掘一下可以看出>:

PS C:\> (Get-Command Set-Location).Parameters['LiteralPath'] |Select Aliases

Aliases
-------
{PSPath}

提供程序 cmdlet 的管道绑定(bind)以这种方式实现的真正原因是双重的:

  1. 将“provider-native”字符串表示直接绑定(bind)到 Path 可能会产生与globbing 相关的意外后果
    • Get-Item -Path 'a[bcd]'Get-Item -LiteralPath 'a[bcd]' 是两个截然不同 例如查询
  2. 绑定(bind)到提供者限定的 PSPath 值意味着我们可以在不丢失自动绑定(bind)的情况下将位置切换到不同的提供者:
    • 即。 PS 证书:\> $aFile |Get-Content 正常工作

关于PowerShell 开始在文件路径前添加 Microsoft.PowerShell.Core\FileSystem::,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60871093/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com