我想为PowerShell脚本中的文件path生成一个string。 我希望这在Windows和Mac都可以工作。
目前代码被硬编码到窗口中,如path(“\” – > windows,“/” – > unix): $templatep="$CoreRoot\templates\$serviceName"
我改变了这个: $templatep= Join-Path $CoreRoot "templates" $serviceName
它在与Powershell 6.0的mac中工作。 但它不能在我的Windows服务器与Powershell 4.我必须做这样的事情:
$templatep= Join-Path $CoreRoot -ChildPath "templates" | Join-Path -ChildPath $serviceName
任何想法,为什么这只是在我的Mac? 这是在PowerShell 5或6的新function? 我不喜欢pipe道多个joinpath。 有一个更好的方法吗?
谢谢!
首先,使用.NET框架的解决方法 :
[IO.Path]::Combine('a', 'b', 'c')
这在Unix上产生a/b/c
,在Windows上产生a\b\c
,并且方便地支持任意数量的路径组件。
注意:
此解决方法仅适用于文件系统路径,而Join-Path
旨在用于任何PowerShell驱动器提供程序的路径。
确保除了第一个组件以外的其他组件都不是以\
(Windows)或/
(Unix)开始,因为之前的任何组件都被忽略; 例如在Windows上:
[IO.Path]::Combine('\a', '\b', 'c') # -> '\b\c' - '\a' is ignored(!)
请注意, Join-Path
不会显示此行为; 看到我的这个答案的细节。
作为使用 管道对Join-Path
调用进行排序的替代方法 ,您可以简单地使用(...)
(一个子表达式):
Join-Path a (Join-Path bc) # -> 'a\b\c' (on Windows)
我对行为的差异没有任何解释 。 Join-Path -?
显示的语法 在Windows PowerShell v5.1.14393.693
和PowerShell Core v6.0.0-alpha.14
两个平台上是一样的(附带的参数省略):
Join-Path [-Path] <String[]> [-ChildPath] <String> ...
基于这种语法, 调用Join-Path abc
应该会导致语法错误 ,这实际上是Windows上发生的( A positional parameter cannot be found that accepts argument 'c'
),但不在Unix平台上。 [1]
也就是说, 如果Join-Path
与任意数量的路径组件一起工作 ,并且它已经在PowerShell Core中工作的事实也许指向Windows PowerShell即将发生的变化, 那么它肯定会很方便 。
请注意,即使[-Path] <String[]>
是一个数组参数,其目的不是接受单个输出路径的多个子路径组件,而是允许连接多个父子路径对; 例如:
$ Join-Path a,bc # same as: Join-Path -Path a,b -ChildPath c a\c b\c
最后, 尽管这可能不是可取的,但是在两种平台上 , 通常都可以使用硬编码/
作为路径分隔符 ,因为许多Windows API函数以及PowerShell自己的cmdlet都可以接受和/
交换 。
但是,并不是所有的公用事业公司都可以这样做,所以使用平台适当的分离器通常更安全。
例如,以下在Windows上工作得很好:
Get-Item c:/windows/system32 # same as: Get-Item c:\windows\system32
严格地说,并不是关于平台 ,而是PowerShell版本 :即使在Windows上, Join-Path abc
在多平台PowerShell核心版本中运行,而不是在Windows本机Windows PowerShell版本中运行(截至v5。 1)。 也就是说,PowerShell Core通常只在Unix平台上使用。