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

时间:2013-07-03 15:43:37

标签: 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扩展为空字符串,即使它们已被转义。为什么呢?

4 个答案:

答案 0 :(得分:49)

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

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


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

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

$s = "share"
join-path "C:\temp\$share" 'Share\ISO$OEM$'
# Output
C:\temp\Share\ISO$OEM$

答案 1 :(得分:9)

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

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

[SUCCESS] 将双引号用作带反斜杠后缀的容器作为转义:

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

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

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

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

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

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

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

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

更新:如果上述内容不够混淆,当您使用函数调用而不是命令时,需要单引号而不转义。尝试在函数调用参数上使用转义将工作:

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

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

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

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

答案 2 :(得分:7)

实际上,您可以像这样使用勾号来逃避$

`$

示例:

$number = 5
Write-Host "`$${number}"
# Output: $5

答案 3 :(得分:0)

就我而言,我需要转义一些$,而不是字符串中的其他变量。

例如,我的SSRS实例名称带有$符号:

  

[ReportServer $ SSRS]

为避免$符号,我使用单引号。否则,我将使用-join语句将变量与包含实际$符号的字符串连接起来。

 $sql = -join('ALTER DATABASE [ReportServer$', $instanceName,'TempDB]
  SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
  GO

  USE [master]
  RESTORE DATABASE [ReportServer$', $instanceName,'TempDB] FROM  DISK = N''C:\temp\ReportServerTempDB.BAK'' WITH  FILE = 1,
    MOVE N''ReportServerTempDB'' TO N''', $sqlDataDrive + "\data_" + $instanceName, '\ReportServer$', $instanceName,'TempDB.mdf'', 
    MOVE N''ReportServerTempDB_log'' TO N''', $sqlLogDrive + "\log_" + $instanceName, '\ReportServer$', $instanceName,'_TempDBlog.LDF'',  NOUNLOAD,  REPLACE, RECOVERY,  STATS = 5
  GO

  ALTER DATABASE [ReportServer$', $instanceName,'TempDB]
  SET MULTI_USER;
  GO
  ')