gpt4 book ai didi

windows - PowerShell如何处理路径中的 “.”?

转载 作者:可可西里 更新时间:2023-11-01 09:57:19 29 4
gpt4 key购买 nike

打开PowerShell终端时,请考虑以下命令序列:

PS C:\Users\username> cd source
PS C:\Users\username\source> $dir = ".\temp"
PS C:\Users\username\source> [System.IO.Path]::GetFullPath($dir)
C:\Users\username\temp

现在这个:
PS C:\Users\username> cd source
PS C:\Users\username\source> powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\Users\username\source> $dir = ".\temp"
PS C:\Users\username\source> [System.IO.Path]::GetFullPath($dir)
C:\Users\username\source\temp

PowerShell为什么解释“。”相对于启动PowerShell的目录,而不是当前目录?我怎样才能解释“。”相对于当前目录?

最佳答案

js2010's helpful answer所述,.NET方法的使用引起了问题:
.NET通常在设计上是单一的,进程范围的当前目录[1],与PowerShell的特定于运行空间的目录不同。

这具有以下含义:

  • 由于,PowerShell本身确实可靠地将.解释为当前位置(这是PowerShell对当前目录概念的概括,该目录也可以引用其他PowerShell驱动器提供程序公开的驱动器(例如注册表)上的其他类型的位置提供程序),则可以使用PowerShell命令(如果有)来避免此问题。
  • 当您调用.NET方法时,请确保事先将绝对路径的所有相对路径解析为,或者在支持的情况下另外提供当前PowerShell文件系统位置作为引用目录-这避免了当前目录不匹配的问题。
  • (另一个但次优的选择是,每当传递一个相对路径时,首先设置[Environment]::CurrentDirectory = $PWD.ProviderPath,但这很笨拙,如果同一进程中可能存在多个PowerShell运行空间,则不应使用。)

  • 下一节将说明如何安全地将相对PowerShell路径传递给.NET方法,而下一节将解决您的问题中的特定问题:如何将给定的PowerShell任意路径解析为绝对的 native 文件系统路径。

    将已知的相对PowerShell路径安全地传递到.NET方法:

    如前所述,当前目录中的差异要求将绝对路径传递给基于PowerShell当前目录的.NET方法。

    这些示例假定将相对路径someFile.txt传递给.NET方法[IO.File]::ReadAllText()
    注意,使用了简单的字符串插值,并使用/(可以与\互换使用)来连接路径组件。如果当前目录恰好是根目录,那么您将得到2个路径分隔符,但这不会影响功能。但是,如果仍然需要避免这种情况,请改用Join-Path cmdlet。
  • 通过$PWD进行的最简单但不完全健壮的(如果当前目录基于使用New-PsDrive创建的特定于PowerShell的驱动器,或者当前位置不是文件系统位置,则失败):
  • [IO.File]::ReadAllText("$PWD/someFile.txt")
  • 更强大的:通过$PWD.ProviderPath(将基于PowerShell驱动器的路径解析为基础 native 文件系统路径,但如果当前位置不是文件系统位置,则仍然会失败):
  • [IO.File]::ReadAllText("$($PWD.ProviderPath)/someFile.txt")
  • 完全健壮的:通过(Get-Location -PSProvider FileSystem).ProviderPath
  • [IO.File]::ReadAllText("$((Get-Location -PSProvider FileSystem).ProviderPath)/someFile.txt")

    注意:以上内容适用于存在和不存在的路径;如果已知存在该路径(例如[IO.File]::ReadAllText()而不是[IO.File]::WriteAllText()),则也可以使用以下命令,但前提是您可以进一步假设当前位置是文件系统位置:
    [IO.File]::ReadAllText((Convert-Path -LiteralPath someFile.txt))

    不幸的是,Convert-PathResolve-Path仅适用于现有路径(从PowerShell Core 7.0.0-preview.3开始);为不存在的路径提供选择加入是proposed on GitHub

    同样,如果Convert-PathResolve-Path支持-PSProvider参数以允许明确指定目标提供程序,则将很有帮助,因为Get-Location已经支持-请参见this suggestion on GitHub

    将给定的任意PowerShell文件系统路径解析为绝对 native 路径:

    如果路径存在,请使用Convert-Path 将任何PowerShell文件系统路径解析为绝对的,文件系统本地的路径:
    $dir = "./temp"
    Convert-Path -LiteralPath $dir

    相关的Resolve-Path cmdlet提供了类似的功能,但是它不会将基于PowerShell特定驱动器(使用New-PsDrive创建)的路径解析为其基础 native 文件系统路径。

    如果尚未存在该路径:

    在基于.NET Core的PowerShell Core 中,您可以使用新的 [IO.Path]::GetFullPath() 重载,即接受引用目录作为指定的相对路径:
    $dir = "./temp"
    [IO.Path]::GetFullPath($dir, $PWD.ProviderPath)

    请注意如何将当前位置的 native 文件系统路径$PWD.ProviderPath作为引用目录传递。

    警告:如果当前位置可能位于文件系统驱动器以外的驱动器上,请使用(Get-Location -PSProvider FileSystem).ProviderPath可靠地引用当前文件系统位置(目录)。

    在Windows PowerShell的中,可以使用[IO.Path]::Combine()
    进行 ,但是请注意,如果您不希望在结果路径中使用./前缀,则必须手动删除它:
    $dir = "./temp"
    [IO.Path]::Combine($PWD.ProviderPath, $dir -replace '^.[\\/]')

    [1]尽管一个给定的进程通常只有一个PowerShell运行空间( session ),但多个进程可能并存于一个进程中,这意味着从概念上讲,所有这些进程都不可能将其单个工作目录与一个唯一的进程进行同步- .NET工作目录。有关更深入的说明,请参见this GitHub issue

    关于windows - PowerShell如何处理路径中的 “.”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57776262/

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