PowerShell 中的转义反引号“`”和反斜杠“\”有什么区别?

What is the difference between the escape backtick "`" and backslash "\" in PowerShell?

我知道两者都在 PowerShell 中使用,但用于不同的上下文。

互联网上关于这个主题的信息很少,唯一谈论它(没有让我理解这个概念)的网站是:
https://www.rlmueller.net/PowerShellEscape.htm

我是 PowerShell 的初学者,我最近正在接触它。
\ 转义的用例出现在我的另一个主题的答案中:

有没有人可以通过示例和用例向我详细解释 PowerShell 中转义反引号 ` 和反斜杠 \ 之间的区别?

欢迎至少提供一种来源,但这不是强制性的。

反引号 ` 在 Powershell 中用作 escape character。也就是说,转义引号、制表符等等。与许多其他环境不同,Powershell 的换行符是 `n,而不是 \n。这有简化路径的好处,因为那些在 Windows.

中使用反斜杠

举一个实际的例子,在许多编程语言中,需要对路径中的反斜杠进行转义。如果您的应用程序位于

c:\program files\newApplication\myApp.exe

它的路径必须写成

c:\program files\newApplication\myApp.exe

双反斜杠表示法实际上是一个反斜杠,而不是制表符或换行符等元字符。请注意,该路径包含 \newApplication。现在,\n 通常表示换行符,但显然不是这样。文件不在

c:\program files\
ewApplication\myApp.exe

毕竟,不是吗?

Powershell 中不需要转义,因为反斜杠本身没有特殊含义。当 Powershell 看到 c:\program files\newApplication\myApp.exe 时,它不会为前面提到的 \n 部分赋予任何特殊含义,它只是一个字符串文字。

反斜杠 \ 用作正则表达式中的转义字符并表示元字符。也就是说,要匹配正则表达式中的文字 *,必须对其进行转义,以免它表示 Kleene 星号(零个或多个匹配项)。

vonPryz's helpful answer 很好地覆盖了 PowerShell-internal 角度;让我尝试一个系统的总结,包括 PowerShell CLI 角度,以及将带有嵌入式 " 的参数传递给外部程序:

一个PowerShell会话中,只有转义字符是`(即所谓的反引号),在以下上下文中:

  • expandable string ("...", double quoted), but not inside a verbatim string ('...', single-quoted); for the supported escape sequences, see the conceptual about_Special_Characters 帮助主题中:

    # " must be escaped; escape sequence `n expands to a newline.
    "3`" of`nrain" 
    
  • 在未加引号的 命令参数中 :

    # > must be escaped to write verbatim 'a>b', 
    # since outside a quoted string an unescaped > is a redirection.
    Write-Output a`>b  
    
  • 对于行继续:

    # Spread the Get-Date call across two lines.
    # Important: ` must be the *very last char* on the line.
    Get-Date `
      -Year 2525
    
  • 注意:各种 子系统 ,无论是否特定于 PowerShell,都可能有自己的转义规则,例如 \ in regular expressions and ` in wildcard expressions.由于这些子系统的参数是通过 PowerShell 字符串 传递的 ,因此最好使用 verbatim 字符串文字,以避免混淆 PowerShell 自己的字符串插值和目标子系统最终会看到什么;例如'A fine.' -match '$50'\ 需要从字面上处理正则表达式元字符 $)。


当从外部调用 PowerShell 时,通过其 CLI不同的 规则适用,可能另外

为了遵守 CLI(命令行界面,通过命令行接受参数的程序)广泛使用的约定 Windows:

  • 在调用 powershell.exe 时,Windows PowerShell CLI" 字符必须用反斜杠 转义 - 即 \" - 为了成为 原始命令行.

    解析期间保留
  • pwsh.exe, the CLI of the cross-platform, install-on-demand PowerShell (Core) 7+ edition,现在值得称道的是或者接受"" [1] 代替 \",这使得来自 cmd.exe 的调用更加稳健。要在 Windows PowerShell 中获得相同的稳健性 - 仅从 cmd.exe - 使用 "^""(原文如此) .
    请注意,与 \" 不同,这些转义序列仅在 (未转义的)"..." 字符串 (例如,pwsh.exe -c " ""you & I"" "powershell.exe -c " "^""you & I"^"" " 中有效

相比之下,unescaped "命令上有syntactic函数行并告诉 PowerShell 参数之间的边界在哪里;这些 " 个实例在命令行解析期间被 删除

这确保外部调用者只想调用带参数的 PowerShell 脚本文件 (.ps1),使用 -File 参数,可以使用常规语法,不需要特殊情况调用 PowerShell 的 CLI。

但是,如果您将包含 PowerShell 代码 的字符串传递给 CLI,使用 -Command 参数,PowerShell 会怎样最终解释显然必须是语法上有效的 PowerShell 代码。

警告:如果您既未指定 -Command 也未指定 -File

  • powershell.exe 默认为 -Command
  • pwsh.exe 现在默认为 -File

有关 -File-Command 调用之间的差异以及何时使用它们,请参阅

如果使用-Command,则有两个,顺序解析阶段:

  • 命令行 解析阶段,其中句法(未转义)" 已删除,并转义 \"(或 "")变成文字 ".

  • 这个阶段的结果然后解析为PowerShell代码,因为它将来自 PowerShell 会话内部。

因此,您可能需要结合 \`-转义;例如(来自 cmd.exe 的电话):

C:>powershell.exe -Command " \"3`\" of snow as of $(Get-Date)\" "

3" of snow as of 11/04/2021 14:13:41

注意使用 `\" 以使 PowerShell 看到 `",即在 "..." 字符串中正确转义的 "之后命令行解析.

或者,根据您传递给 -Command 的命令的具体情况,使用 嵌入 '...' 引用 可能 是一个选项,这简化了事情,因为' 个字符。不需要转义:

C:>powershell.exe -Command " '3\" of snow as of today.' "

3" of snow as of today.

鉴于 PowerShell 中的 '...' 字符串是 verbatim strings,如果您不需要字符串插值(例如 $(Get-Date),则使用 '...' 只是一个选项前面示例中的子表达式)。


从调用外部程序时转义" PowerShell:

作为shell,PowerShell的工作是将基于its语法规则传递的参数传递给一个目标可执行文件,以便从 PowerShell 的解析中得到的逐字值以一种使目标可执行文件看到它们的方式传递。换句话说:PowerShell 应该在幕后自动执行任何需要的转义。 (与 cmd.exe 不同,PowerShell 不能按原样传递自己的参数语法,因为不能期望外部 CLI 理解 '...' 字符串(单引号)或 `-转义)。

举个简单的例子:根据最广泛使用的转义约定,传递 '3" of snow' 应该 在幕后作为 "3\" of snow" 传递。

可悲的是,至少 PowerShell 7.2(撰写本文时为当前版本),不是情况,并且外部程序的参数中嵌入"个字符必须另外,手动 \-转义 以便正确通过。

# Broken behavior up to at least PS v7.2

PS> cmd /c echo '{ "foo": "bar" }'
"{ "foo": "bar" }"  # !! Embedded " aren't escaped.

PS> choice.exe /d Y /t 0 /m '{ "foo": "bar" }'
{ foo: bar } [Y,N]?Y  # !! When parsed by an executable, 
                      # !! embedded " are effectively LOST.

# Manual escaping required.
PS> choice.exe /d Y /t 0 /m '{ \"foo\": \"bar\" }'
{ "foo": "bar" } [Y,N]?Y  # OK

此错误自 v1 以来就存在,并且从未修复以避免破坏现有的解决方法。 此 可能 最早在 v7.3 中更改 - 以及修复是否需要 是否选择加入 对我来说并不清楚,而且看起来不符合要求的 Windows CLI 也不会被接纳。

有关详细信息,请参阅 ,其中包括相关 GitHub 问题的链接。


[1] 在 PowerShell 中,仅在 "..." 字符串中,您还可以使用 "" 来转义嵌入的 ",作为 `"