powershell 解析相对于给定基路径可能不存在的路径

v7pvogib  于 2023-10-18  发布在  Shell
关注(0)|答案(1)|浏览(122)

在PowerShell(v5或核心)中是否有一种方法来解析相对于给定的基本路径可能不存在的路径?注意:我还想确保如果给定的“相对路径”实际上是一个绝对路径,它仍然可以正确地解析。
我已经可以通过改变工作目录来做到这一点;但我想有一种方法来做到这一点,而不改变我的工作目录(因为我不喜欢副作用)。是否有一个本机替代下面的功能?

Function Resolve-RelativePath {
    Param (
        [Parameter(Mandatory)]
        [string]$Path
        ,
        [Parameter()]
        [string]$BasePath = '.'
    )
    Push-Location -Path $BasePath -ErrorAction Stop # the base path must exist; it's only the relative path which doesn't have to
    try {
        $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
    } finally {
        Pop-Location # try to avoid side effects
    }
}

注意:为了确认我的预期,运行下面的函数应该会返回true,用于下面的“测试”:

# ensure our base path exists for the below demos
New-Item -Path 'c:\temp\demo\ChildFolderThatExists'  -ItemType Directory -Force | Out-Null
New-Item -Path 'c:\temp\demo2\ChildFolderThatExists' -ItemType Directory -Force | Out-Null 
Set-Location -Path 'c:\temp\demo'

# the "tests"
(Resolve-RelativePath -Path 'ChildFolderThatExists'                                   ) -eq 'c:\temp\demo\ChildFolderThatExists'
(Resolve-RelativePath -Path 'ChildFolderThatDoesntExist'                              ) -eq 'c:\temp\demo\ChildFolderThatDoesntExist'
(Resolve-RelativePath -Path '../../someOtherFolder/Whatever'                          ) -eq 'c:\someOtherFolder\Whatever'
(Resolve-RelativePath -Path 'c:\absolute'                                             ) -eq 'c:\absolute'

(Resolve-RelativePath -Path 'ChildFolderThatExists' -BasePath 'c:\temp\demo2'         ) -eq 'c:\temp\demo2\ChildFolderThatExists'
(Resolve-RelativePath -Path 'ChildFolderThatDoesntExist' -BasePath 'c:\temp\demo2'    ) -eq 'c:\temp\demo2\ChildFolderThatDoesntExist'
(Resolve-RelativePath -Path '../../someOtherFolder/Whatever' -BasePath 'c:\temp\demo2') -eq 'c:\someOtherFolder\Whatever'
(Resolve-RelativePath -Path 'c:\absolute' -BasePath 'c:\temp\demo2'                   ) -eq 'c:\absolute'
axr492tv

axr492tv1#

我在.net core中找到了解决方案

$Path = 'c:\temp\demo'
$RelativePath = 'ChildFolderThatExists'
[System.IO.Path]::GetFullPath($Path, $RelativePath)

注意:.net framework中不存在提供基本路径的选项,因此这仅在PWSH中有效。
为了确保这适用于两个版本的PowerShell,并避免在如何解决.方面存在一些差异,这里是上述函数的更新版本,它在PWSH中没有副作用,但仍然使用旧PowerShell版本中的Push-Location解决方案。

Function Resolve-RelativePath {
    Param (
        [Parameter(Mandatory)]
        [string]$Path
        ,
        [Parameter()]
        [string]$BasePath = '.'
    )
    if (($PSVersionTable.PSEdition -eq 'Core') -or ([Environment]::Version.Major -ge 5)) { # environemt version is the better check, but doesn't exist in all versions: https://github.com/dotnet/corefx/commit/fe5f4fbebc9e85c8e512a273567719dca15ac764
        $BasePath = [System.IO.Path]::GetFullPath($BasePath, (Get-Location))
        [System.IO.Path]::GetFullPath($Path, $BasePath)
    } else {
        Push-Location -Path $BasePath -ErrorAction Stop # the base path must exist; it's only the relative path which doesn't have to
        try {
            $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
        } finally {
            Pop-Location # try to avoid side effects
        }
    }
}

# ensure our base path exists for the below demos
New-Item -Path 'c:\temp\demo\ChildFolderThatExists'  -ItemType Directory -Force | Out-Null
New-Item -Path 'c:\temp\demo2\ChildFolderThatExists' -ItemType Directory -Force | Out-Null 
Set-Location -Path 'c:\temp\demo'

# the "tests"
(Resolve-RelativePath -Path 'ChildFolderThatExists'                                   ) -eq 'c:\temp\demo\ChildFolderThatExists'
(Resolve-RelativePath -Path 'ChildFolderThatDoesntExist'                              ) -eq 'c:\temp\demo\ChildFolderThatDoesntExist'
(Resolve-RelativePath -Path '../../someOtherFolder/Whatever'                          ) -eq 'c:\someOtherFolder\Whatever'
(Resolve-RelativePath -Path 'c:\absolute'                                             ) -eq 'c:\absolute'

(Resolve-RelativePath -Path 'ChildFolderThatExists' -BasePath 'c:\temp\demo2'         ) -eq 'c:\temp\demo2\ChildFolderThatExists'
(Resolve-RelativePath -Path 'ChildFolderThatDoesntExist' -BasePath 'c:\temp\demo2'    ) -eq 'c:\temp\demo2\ChildFolderThatDoesntExist'
(Resolve-RelativePath -Path '../../someOtherFolder/Whatever' -BasePath 'c:\temp\demo2') -eq 'c:\someOtherFolder\Whatever'
(Resolve-RelativePath -Path 'c:\absolute' -BasePath 'c:\temp\demo2'                   ) -eq 'c:\absolute'

相关问题