【问题标题】:How to concatenate string variables with backslashes to create a UNC path in Powershell如何使用反斜杠连接字符串变量以在 Powershell 中创建 UNC 路径
【发布时间】:2017-07-27 12:45:53
【问题描述】:

这似乎应该是一件微不足道的事情。

我正在使用 Powershell v5.1,我正在尝试从代表服务器和共享的 2 个字符串构建 UNC 路径。鉴于 $Server 持有“分发”并且 $Share 持有“发布”...

 $Path = "\\" + $Server + "\" + $Share

$Path 我得到的输出是..

\\Distribution Publish\

我尝试将其更改为...

$Path = "//" + $Server + "/" + $Share

...作为一个测试,认为特殊字符“\”引起了问题,但我仍然得到奇怪的序列,服务器和共享之间有一个空格,第二个斜杠在末尾。

//Distribution Publish/

我错过了什么?

【问题讨论】:

  • 您确定$server$share 包含您的想法,而实际上它们不是$server == "Distribution Publish"$share == ""?你有什么should be fine.
  • 无法在 PowerShell 5 中重现,这确实很奇怪。检查 $Server.Length$Share.Length 以查看它们是否包含任何可能影响结果的有趣的不可见字符(如 RTL 标记)。
  • 作为双引号内的替换函数,$Path = "\\$Server\$Share" 会做你想做的事。
  • @JamesC.:虽然这是真的,而且通常是一个更简洁的替代方案,但它相当于 OP 尝试过的,因此没有解释症状。

标签: powershell powershell-4.0


【解决方案1】:

如 cmets 中所述,如果您的 $Server$Share 变量真正分别包含 DistributionPublish,则您的症状无法解释,没有隐藏控制字符.

这是一个人为的变量值示例,确实会产生您的症状:

> $Server = 'Distribution', 'Publish'; $Share = "`r"; "\\" + $Server + "\" + $Share
\\Distribution Publish\

正如 James C. 指出的那样,构建字符串的更简洁的替代方法是:"\\$Server\$Share"
正如 TheIncorrigible1 指出的那样,最好使用Join-Path 构建路径。

  • 'Distribution', 'Publish' 是字符串的数组,其元素 PowerShell 在将其转换为字符串时与空格连接(默认情况下),在此案例结果为Distribution Publish

  • "`r" 创建控制字符 CR (0xD),当打印到控制台时,将光标位置重置到 第一列 和在那里打印字符串的其余部分(在本例中为空)。
    但是请注意,CR 仍然是字符串的一部分,尽管它是不可见的。
    如果您想要一种简单的方法来检查给定字符串中是否存在隐藏的控制字符,请参阅我的 this answer


更新

OP 报告说,$Server$Share 变量是如何通过参数绑定的,通过错误使用 (C#) 方法调用语法强>:

# Correct invocation: $Server binds to 1st parameter, $Share to 2nd.
./script $Server $Share

# INCORRECT: Binds *both* values to the *first* parameter, as an *array*
#            and assigns nothing to the second.
#            In PowerShell, "," constructs an array.
./script($Server, $Share) 

棘手的是./script($Server, $Share) 恰好也是有效的 PowerShell 语法,只是语义不同:$Server, $Share 构造一个 2 元素 数组,其元素是 $Server$Share

为了避免这个陷阱,PowerShell 提供了严格模式设置Set-StrictMode -Version 2,它会在尝试方法样式调用时报告错误。但是请注意,此设置总是会启用其他检查,尤其是在引用不存在的属性时会导致错误 - 请参阅Get-Help Set-StrictMode

【讨论】:

  • @EiEiGuy:很高兴听到这个消息。我懂了;是的,传递参数 C# 风格是一个常见的陷阱 - 请参阅我的更新。
【解决方案2】:

避免像使用路径时那样添加字符串;有 cmdlet 可以处理。

$Server = '\\This.server.name'
$File = 'something.exe'
$UNC = Join-Path $Server $File

此外,如果遇到奇怪的错误,请进行字符串验证。

If (!$Server) { "Stuff"; Return } # Checks empty string
If (!$File)   { "Stuff"; Return }
If (!(Test-Path $UNC)) { "Stuff"; Return } # error checking for the file

【讨论】:

  • 我正在做的是接受服务器名称和共享名称作为我的文件复制脚本的参数,并尝试预先验证目标 UNC。我正在剥离任何用户提供的“\”或“/”字符,然后在调用 Test-Path 之前构建正确的 \\server\share 路径。不过,我会给你一个 +1 的加入路径
  • 是的,Join-Path 是个好建议。 @TheIncorrigible1:但是,您的 UNC 路径缺少 share 组件。另外,我建议不要使用Return 进行错误处理。
  • 是的,理想情况下您会使用[CmdletBinding()]$PSCmdlet.ThrowTerminatingError(),但这是一个简单的示例。共享可以在$Server 变量中指定,或者更恰当地重命名为$Share
猜你喜欢
  • 2010-12-26
  • 2018-11-15
  • 1970-01-01
  • 2020-08-28
  • 2012-04-19
  • 2022-11-19
相关资源
最近更新 更多