Powershell在windows和unix中正确生成文件path

我想为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。 有一个更好的方法吗?

谢谢!

Solutions Collecting From Web of "Powershell在windows和unix中正确生成文件path"

首先,使用.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.693PowerShell 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平台上使用。