Windows PowerShell是如何处理的&引用;在小路上?
打开PowerShell终端时,请考虑以下命令序列:Windows PowerShell是如何处理的&引用;在小路上?,windows,powershell,Windows,Powershell,打开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:\Use
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的目录而不是当前目录解释“.”?如何才能让它相对于当前目录解释“.”?这更像是一个.net问题: 常见的解决方法:
[xml]$xml = cat file.xml
$xml.save("$pwd\file.xml")
Powershell将
视为当前位置。因此,如果您执行getchilditem-Path“\”
,这将返回当前目录中的所有内容。要获得相对路径,您需要执行以下操作:
Set-Location -Path "Path"
$path = Get-Item -Path "file" | Resolve-Path -Relative
$path
现在将是一个相对路径正如所述,使用.NET方法引入了问题:.NET的单一进程范围的当前目录通常在设计上[1]与PowerShell的特定于运行空间的目录不同。 这有以下影响:
- 由于PowerShell本身确实可靠地将
解释为当前位置(这是PowerShell对当前目录概念的概括,当前目录也可以引用由其他PowerShell驱动器提供程序(如注册表提供程序)公开的驱动器上的其他类型的位置),如果可用,您可以使用PowerShell命令来避免此问题 - 在调用.NET方法时,请确保事先将任何相对路径解析为绝对路径,或者在支持的情况下,另外提供当前PowerShell文件系统位置作为参考目录-这避免了当前目录不匹配的问题
- (另一个次优选项是每次传递相对路径时首先设置
,但这很笨拙,如果同一进程中可能存在多个PowerShell运行空间,则不应使用。)[Environment]::CurrentDirectory=$PWD.ProviderPath
- (另一个次优选项是每次传递相对路径时首先设置
将已知的相对PowerShell路径安全地传递给.NET方法: 如上所述,当前目录中的差异要求将绝对路径传递给.NET方法,该方法基于PowerShell的当前目录到达 示例假定相对路径
someFile.txt
将传递给.NET方法[IO.File]::ReadAllText()
注意,使用简单的字符串插值,并使用/
(可与\
互换使用)连接路径组件;如果当前目录恰好是根目录,那么最终将使用2个路径分隔符,但这不会影响功能。但是,如果仍然需要避免这种情况,请改用Join-Path
cmdlet
- 通过
(如果当前目录基于使用$PWD
创建的特定于PowerShell的驱动器,或者如果当前位置不是文件系统位置,则会失败)最简单,但不完全健壮的:新PsDrive
- 更健壮:通过
(将基于PowerShell驱动器的路径解析为底层本机文件系统路径,但如果当前位置不是文件系统位置,则仍可能失败):$PWD.ProviderPath
- 完全健壮:通过
(获取位置-PSProvider文件系统)。ProviderPath
[IO.File]::ReadAllText()
,而不是使用[IO.File]::WriteAllText()
-您也可以使用以下选项,但前提是您可以进一步假设当前位置是文件系统位置:
[IO.File]::ReadAllText((Convert-Path -LiteralPath someFile.txt))
不幸的是,转换路径
和解析路径
仅适用于现有路径(从PowerShell Core 7.0.0-preview.3开始);已为不存在的路径提供选择加入
类似地,如果转换路径
和解析路径
支持-PSProvider
参数以允许显式指定目标提供程序,这将非常有用,因为获取位置
已经支持此参数-请参阅
将给定的任意PowerShell文件系统路径解析为绝对本机路径: 如果路径存在,请使用
转换路径
将任何PowerShell文件系统路径解析为绝对的文件系统本机路径:
$dir = "./temp"
Convert-Path -LiteralPath $dir
相关的Resolve-Path
cmdlet提供了类似的功能,但它无法将基于PowerShell特定驱动器(使用New PsDrive
创建)的路径解析为其底层本机文件系统路径
如果路径不存在(尚未):
在构建于.NET Core之上的PowerShell Core中,您可以使用新的[IO.Path]::GetFullPath()
重载,该重载接受指定相对路径的引用目录:
$dir = "./temp"
[IO.Path]::GetFullPath($dir, $PWD.ProviderPath)
注意当前位置的本机文件系统路径,$PWD.ProviderPath
,是如何作为引用目录传递的
警告:如果当前位置可能位于文件系统驱动器以外的驱动器上,请使用(获取位置-PSProvider filesystem)。ProviderPath
可靠地引用当前文件系统位置(目录)
在Windows PowerShell中,您可以使用[IO.Path]::Combine()
,但请注意,如果您不希望前缀出现在结果路径中,则必须手动删除前缀/
:
$dir = "./temp"
[IO.Path]::Combine($PWD.ProviderPath, $dir -replace '^.[\\/]')
[1] 虽然给定的进程通常只有一个PowerShell运行空间(会话),但一个进程中多个运行空间共存的可能性意味着这是一个概念
$dir = "./temp"
Convert-Path -LiteralPath $dir
$dir = "./temp"
[IO.Path]::GetFullPath($dir, $PWD.ProviderPath)
$dir = "./temp"
[IO.Path]::Combine($PWD.ProviderPath, $dir -replace '^.[\\/]')