为什么函数[System.IO.Path]::Combine
不接受我的第一个参数?
PS C:WINDOWSsystem32> $g_basePath
F:DevOneClickTools
PS C:WINDOWSsystem32> [Tests.Utils]::CUSTOMASSEMBLY_TEST
CustomLogic.dll
PS C:WINDOWSsystem32> [System.IO.Path]::Combine($g_basePath, "bindebug", [Tests.Utils]::CUSTOMASSEMBLY_TEST)
bindebugCustomLogic.dll
第三个命令显示只有第二个和第三个参数连接在一起,还是使用了一个空字符串作为$g_basePath
。。?
补充Martin Brandl的有用答案:
具体地说,[System.IO.Path]::Combine
应用的反直觉逻辑是:;如果path2或path3也是绝对路径,则合并操作将丢弃所有先前合并的路径并重置为该绝对路径"(这也适用于其他方法重载)。
换句话说:指定的以(包括
\
)或<letter>:
(驱动器规范)开头的最后一个路径参数会导致忽略所有以前的路径
PS> [IO.Path]::Combine('foo', 'bar', 'baz')
baz # !! 'foo' and 'bar' were ignored
对于预期的行为——初始应被视为除第一个之外的每个路径组件的可选部分——确保除第一个之外的每个组件都不以
开头——
Join-Path
按预期处理。
简单函数可以做到这一点:
# Combines array of path components $a to a single path.
function combine([string[]] $a) {
[IO.Path]::Combine([string[]] (@($a[0]) + $a[1..$($a.count-1)] -replace '^\', ''))
}
请注意,转换为[string[]]
对这一操作至关重要。
示例调用:
PS> combine 'foo', 'bar', 'baz'
foobarbaz # as expected
使用Join-Path
,仅支持对组件(自Windows PowerShell v5.1[1]起),使用管道链接多个调用的替代方法是用(...)
嵌套多个调用:
PS> Join-Path foo (Join-Path bar baz)
foobarbaz
请注意,即使嵌套有些尴尬,也不需要担心以开头的从属组件。
至于PowerShell自己的Join-Path
cmdlet的逻辑:
虽然期望-ChildPath
参数支持路径的数组是可以理解的(事实并非如此),但重要的是要理解Join-Path
的设计与[System.IO.Path]::Combine()
的设计有根本不同,因为Windows PowerShell v5.1[1]:
Join-Path
使用多个输入路径来生成多个输出路径,而不是将输入路径解释为单个输出路径的组件。输入路径是父路径和子路径的对,每对都被连接并产生自己的输出路径:
PS> Join-Path foo bar foobar
- 缩写:
Join-Path -Path foo -ChildPath bar
- 请注意,与
[System.IO.Path]::Combine()
不同,PS是如何处理子路径中可选的前导的
- 缩写:
虽然父路径参数(
-Path
)确实支持父路径的数组,但子路径参数(-ChildPath
)不支持,尽管与-Resolve
参数和通配符组合使用时,它可以有效地生成多个子路径。PS> Join-Path -Path foo, baz -ChildPath bar foobar bazbar
- 请注意2输出路径是如何通过将每个父路径和一个子路径配对生成的
与
[System.IO.Path]::Combine()
不同,Join-Path
可选地支持使用-Resolve
:解析通配符路径PS> Join-Path -Resolve C:Win* Sys* C:WindowsSystem C:WindowsSystem32 C:WindowsSystemApps C:WindowsSystemResources C:WindowsSysWOW64 C:Windowssystem.ini
最后,值得注意的是,
Join-Path
不仅适用于文件系统路径,还适用于任何PowerShell[分层数据存储]提供程序的路径,并应用提供程序适当的路径分隔符。
[1]跨平台PowerShell版本,PowerShell核心,自v6.0.0起,已经支持任意数量的子组件、启用Join-Path a b c
等调用以生成abc
(Windows)或a/b/c
(Unix),而自v5.1起的Windows本机Windows PowerShell版本仍然不支持它。
此新行为尚未记录在案(甚至未在Join-Path -?
中反映语法),但它最终可能会进入Windows PowerShell(从而进入所有版本)。
只需省略第二个路径上的前导反斜杠:
[System.IO.Path]::Combine($g_basePath, "bindebug", [Tests.Utils]::CUSTOMASSEMBLY_TEST)
纯PowerShell尝试将使用Join-path cmdlet两次:
Join-Path $g_basePath 'bindebug' | Join-path -ChildPath [Tests.Utils]::CUSTOMASSEMBLY_TEST