在PowerShell路径中转义美元符号无法正常工作

Bel*_*lac 27 powershell

为什么这不起作用?


$drvrInstFilePath = "$sharePath\$imageName\ISO`$OEM$`$1\RPKTools\RPKDriverInst.bat"
echo $drvrInstFilePath
$drvrInstContent = Get-Content -LiteralPath "$sharePath\$imageName\ISO`$OEM$`$1\RPKTools\RPKDriverInst.bat"  | Out-String

echo显示正确的路径,但Get-Content命令将$ oem和$ 1扩展为空字符串,即使它们已被转义.为什么?

von*_*ryz 58

而不是乱扔美元符号,使用单引号'而不是双引号".它可以防止PowerShell扩展$为变量.像这样,

$p = "C:\temp\Share\ISO$OEM$"
# Output
C:\temp\Share\ISO$


$p = 'C:\temp\Share\ISO$OEM$'
# Output
C:\temp\Share\ISO$OEM$
Run Code Online (Sandbox Code Playgroud)

如果需要使用变量创建路径,请考虑使用Join-Path.像这样,

$s = "share"
join-path "C:\temp\$share" 'Share\ISO$OEM$'
# Output
C:\temp\Share\ISO$OEM$
Run Code Online (Sandbox Code Playgroud)


小智 25

你实际上可以只使用一个刻度线来逃避$这样的:

`$
Run Code Online (Sandbox Code Playgroud)

例子:

$number = 5
Write-Host "`$${number}"
# Output: $5
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 11

你使用双引号和一个反引号.这是一个错误的组合.事实上,在任何情况下,我都不确定单独的反击是否足够.你在PowerShell中逃避美元符号($)的成功选择是使用双引号和反斜杠反向组合("\`$ find"),或者使用带有简单反斜杠的单引号('\ $ find').[但是,请注意最后关于函数调用参数的异常.]请参阅下面的示例.

此外,对于那些不熟悉这种区别的人来说,重要的是不要在这些转义中混淆反引号字符(`)单引号字符(').

[SUCCESS]双引号作为带有反斜杠反引号的容器作为转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\`$old", "(New)"}
What is (New)?
PS C:\Temp>
Run Code Online (Sandbox Code Playgroud)

[FAIL]双引号作为带有反斜杠撇号的容器作为转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\'$old", "(New)"}
What is $old?
PS C:\Temp>
Run Code Online (Sandbox Code Playgroud)

[SUCCESS]单引号作为容器,带有简单的反斜杠作为转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\$old', "(New)"}
What is (New)?
PS C:\Temp>
Run Code Online (Sandbox Code Playgroud)

[FAIL]单引号作为容器,带反斜杠反引号作为转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\`$old', "(New)"}
What is $old?
PS C:\Temp>
Run Code Online (Sandbox Code Playgroud)

总的来说,最简单的选择可能是使用单引号作为容器,使用单个反斜杠作为转义: '\$old'

更新:如果上面的内容不够混淆,当您使用函数调用而不是命令时,需要单引号而不进行转义.尝试使用的函数调用的参数转义将无法正常工作:

[FAIL]在函数参数中使用转义:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_.ToString().Replace('\$old', "(New)");}
What is $old?
PS C:\Temp>
Run Code Online (Sandbox Code Playgroud)

[SUCCESS]在函数参数中使用没有转义的纯单引号:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_.ToString().Replace('$old', "(New)");}
What is (New)?
PS C:\Temp>
Run Code Online (Sandbox Code Playgroud)

  • 另外,如果在函数调用中使用了“”`引号,则$ old执行字符串插值,并且必须使用..单个反引号对其进行转义,且不带反斜杠。这实际上是有道理的,因为反斜杠是额外的转义符无论如何,当我尝试对字符串进行内插和捕获组替换的Regex.Replace时,我发现了它:`$ regex.Replace($ rawtext,“ $ keyword:\`$ 1”)`如果没有反引号,`$ 1`将在传递给Replace之前进行字符串内插,并且在那里始终会产生空文本,因为没有这样的变量。 (2认同)
  • 我不认为“带有反斜杠-反引号组合的双引号”(“\`$find”)在 PowerShell 5.0 中不再有效...根据 Windows PowerShell 语言规范版本 3.0 第 30 页,单个反引号就足够了。 (2认同)
  • 由于`-Replace`运算符使用正则表达式,因此这些示例很遗憾将使用反引号的常规PowerShell转义与使用反斜杠的正则表达式转义混淆。纯PowerShell字符串不使用反斜杠进行转义。 (2认同)