Powershell 在 windows 和 unix 中正确生成文件路径 [英] Powershell to generate file paths correctly in windows and unix

查看:43
本文介绍了Powershell 在 windows 和 unix 中正确生成文件路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为 powershell 脚本中的文件路径生成一个字符串.我希望它在 windows 和 mac 中都能使用.

I want to generate a string for a file path inside a powershell script. I want this to work in both in windows and mac.

目前代码被硬编码到窗口之类的路径(\" -> windows,/" -> unix):<代码>$templatep="$CoreRoot\templates\$serviceName"

At the moment the code is hardcoded to windows like paths ("\" -> windows, "/" -> unix): $templatep="$CoreRoot\templates\$serviceName"

我将其更改为:<代码>$templatep= Join-Path $CoreRoot "templates" $serviceName它适用于带有 Powershell 6.0 的 Mac.但是它在我的带有 Powershell 4 的 Windows 服务器中不起作用.我必须做这样的事情:

I changed this to: $templatep= Join-Path $CoreRoot "templates" $serviceName And it works in mac with Powershell 6.0. BUT it doesn't work in my windows server with Powershell 4. I have to do something like this:

<代码>$templatep= Join-Path $CoreRoot -ChildPath "templates" |加入路径 -ChildPath $serviceName

知道为什么这仅适用于我的 Mac 吗?这是 powershell 5 或 6 中的新功能吗?我不喜欢必须通过管道连接多个连接路径.有没有更好的方法来做到这一点?

Any idea why this is just working in my mac? Is this a new feature in powershell 5 or 6? I dont't like the having to pipe multiple Join-Paths. Is there a better way to do this?

谢谢!

推荐答案

首先,使用 .NET 框架的解决方法:

First, a workaround using the .NET framework:

[IO.Path]::Combine('a', 'b', 'c')

这在Unix上产生a/b/c,在Windows上产生a\b\c,并且方便地支持任意个路径组件.

This yields a/b/c on Unix, and a\b\c on Windows, and conveniently supports any number of path components.

注意:

  • 此解决方法仅适用于 filesystem 路径,而 Join-Path 旨在与任何 PowerShell 驱动器提供程序的路径配合使用.

  • This workaround is only for filesystem paths, whereas Join-Path is designed to work with any PowerShell drive provider's paths.

确保除了 first 之外没有其他组件以 \ (Windows) 或 / (Unix) 开头,因为任何然后忽略前面的组件;例如,在 Windows 上:
[IO.Path]::Combine('\a', '\b', 'c') # ->'\b\c' - '\a' 被忽略(!)
请注意,Join-Path不会表现出这种行为;有关详细信息,请参阅我的这个答案.

Make sure that no component other than the first starts with \ (Windows) or / (Unix), because any preceding component is then ignored; e.g., on Windows:
[IO.Path]::Combine('\a', '\b', 'c') # -> '\b\c' - '\a' is ignored(!)
Note that Join-Path does not exhibit this behavior; see this answer of mine for details.

作为使用管道Join-Path调用进行排序的替代,您可以简单地使用(...)(子表达式):

As an alternative to sequencing Join-Path calls with a pipeline you can simply use (...) (a subexpression):

Join-Path a (Join-Path b c)  # -> 'a\b\c' (on Windows)


Join-Path -? 显示的语法自 Windows PowerShell v5.1.14393.693 起(省略附带参数):


The syntax displayed by Join-Path -? as of Windows PowerShell v5.1.14393.693 (incidental parameters omitted):

Join-Path [-Path] <String[]> [-ChildPath] <String> ...

根据这个语法,调用Join-Path a b c应该会导致语法错误,这确实发生了.

Based on this syntax, invocation Join-Path a b c should result in a syntax error, which is indeed what happens.

相比之下,PowerShell [Core] v6+ 中显示的语法揭示了一个附加参数:

By contrast, the syntax displayed in PowerShell [Core] v6+ reveals an additional parameter:

Join-Path [-Path] <String[]> [-ChildPath] <String> [[-AdditionalChildPath] <String[]>]

它是附加的 -AdditionalChildPath 参数,它以收集所有剩余位置参数(ValueFromRemainingArguments)的方式声明,即使指定任意数量的子组件起作用,例如,Join-Path abc 确实起作用.

It is the additional -AdditionalChildPath parameter, which is declared in a manner that collects all remaining positional arguments that (ValueFromRemainingArguments), that makes specifying an arbitrary number of child components work, so that Join-Path a b c indeed works, for instance.

不幸的是,此增强功能不会向后移植到 Windows PowerShell.

Unfortunately, this enhancement won't be back-ported to Windows PowerShell.

注意,即使 [-Path] 是一个 array 参数,它的目的不是接受单个的多个子路径组件输出路径,但允许加入多个父子路径对;例如:

Note that even though [-Path] <String[]> is an array parameter, its purpose is not to accept multiple child path components of a single output path, but to allow joining of multiple parent-child path pairs; e.g.:

$ Join-Path a,b c  # same as: Join-Path -Path a,b -ChildPath c
a\c
b\c


最后,即使虽然可能不建议这样做,但您通常可以在两个平台上使用硬编码 / 作为路径分隔符,因为许多 Windows API 函数以及 PowerShell 自己的 cmdlet 接受 \/ 可互换.
但是,并非所有实用程序都可能以这种方式运行,因此使用适合平台的分隔符通常更安全.


Finally, even though it's probably not advisable, you can often get away with hard-coding / as the path separator on both platforms, because many Windows API functions as well as PowerShell's own cmdlets accept \ and / interchangeably.
However, not all utilities may behave this way, so it's generally safer to use the platform-appropriate separator.

例如,以下在 Windows 上运行良好:

For instance, the following works just fine on Windows:

Get-Item c:/windows/system32 # same as: Get-Item c:\windows\system32

这篇关于Powershell 在 windows 和 unix 中正确生成文件路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆