Mar*_*mbo 6 powershell escaping
我知道两者都在 PowerShell 中使用,但用于不同的上下文。
互联网上有关此主题的信息很少,唯一谈论此主题的网站(没有让我理解这个概念)是:
https ://www.rlmueller.net/PowerShellEscape.htm
我是 PowerShell 的初学者,最近才接触它。在我的另一个主题的答案中出现了转义
的用例:当我将参数传递给嵌套的 Start-Process 命令时,PowerShell 删除多个连续的空格\
有谁可以通过示例和用例向我详细解释PowerShell中转义反引号`和反斜杠之间的区别吗\?
至少有一个来源是受欢迎的,但这不是强制性的。
mkl*_*nt0 12
vonPryz 的有用答案很好地涵盖了 PowerShell 的内部角度;让我尝试进行系统总结,其中包括 PowerShell CLI角度,以及通过嵌入"到外部程序传递参数:
在PowerShell 会话内部,唯一的转义字符是`(所谓的反引号),在以下上下文中:
在可扩展字符串内("...",双引号),但不在逐字字符串内('...',单引号);有关支持的转义序列,请参阅概念性about_Special_Characters帮助主题:
# " must be escaped; escape sequence `n expands to a newline.
"3`" of`nrain"
Run Code Online (Sandbox Code Playgroud)
在不带引号的命令参数中:
# > must be escaped to write verbatim 'a>b',
# since outside a quoted string an unescaped > is a redirection.
Write-Output a`>b
Run Code Online (Sandbox Code Playgroud)
对于续行:
# Spread the Get-Date call across two lines.
# Important: ` must be the *very last char* on the line.
Get-Date `
-Year 2525
Run Code Online (Sandbox Code Playgroud)
注意:各种子系统,无论是否特定于 PowerShell,都可能有自己的转义规则,例如\在正则表达式和通配符表达式`中。由于这些子系统的参数是通过 PowerShell strings传递的,因此最好使用逐字字符串文字,以避免 PowerShell 自己的字符串插值与目标子系统最终看到的内容之间发生混淆;例如(需要按字面意思处理正则表达式元字符)。'A $50 fine.' -match '\$50'\$
当从外部通过其CLI调用 PowerShell 时,会应用不同的规则,可能还包括:
为了遵守Windows 上广泛使用的 CLI(命令行界面,通过命令行接受参数的程序)约定:
在调用powershell.exeWindows PowerShell CLI时,"必须使用反斜杠(即 as \")对字符进行转义,以便在解析原始命令行期间保留字符。
pwsh.exe,跨平台、按需安装的PowerShell (Core) 7+版本的 CLI ,现在值得称赞的是可以接受""[1]来代替\",这使得来自的调用cmd.exe更加稳健。要在Windows PowerShell中获得相同的稳健性-cmd.exe仅使用"^""(原文如此)。
请注意,与这些转义序列不同的是,这些转义序列仅在(未转义的)字符串\"中工作(例如,或"..."pwsh.exe -c " ""you & I"" "powershell.exe -c " "^""you & I"^"" "
相比之下,未转义 "在命令行上具有语法功能,并告诉 PowerShell 参数之间的边界在哪里;这些"实例在命令行解析期间被删除。
这确保了只想使用参数调用带参数的 PowerShell脚本文件( .ps1)-File的外部调用者可以使用传统语法,而无需对 PowerShell CLI 进行特殊情况调用。
但是,如果使用参数将包含PowerShell 代码的字符串传递给 CLI-Command,则 PowerShell 最终解释的内容显然必须是语法上有效的 PowerShell 代码。
警告:如果您既不指定-Command也不指定-File:
powershell.exe默认为-Commandpwsh.exe现在默认为-File-File有关和调用之间的差异-Command以及何时使用 which,请参阅此答案。
如果您使用-Command,则有两个连续的解析阶段:
命令行解析阶段,语法(未转义)"被删除,转义\"(或"")变成文字"。
然后,此阶段的结果被解析为PowerShell 代码,就像来自PowerShell会话内部一样。
因此,在某些情况下您可能必须结合使用 \和`-escaping;例如(从 调用cmd.exe):
C:>powershell.exe -Command " \"3`\" of snow as of $(Get-Date)\" "
3" of snow as of 11/04/2021 14:13:41
Run Code Online (Sandbox Code Playgroud)
请注意使用 ,`\"以使 PowerShell在命令行解析后看到,即字符串内`"正确转义的。""..."
或者,根据您传递给的命令的具体情况-Command,使用嵌入式'...'引用可能是一个选项,这可以简化问题,因为'chars. 不需要转义:
C:>powershell.exe -Command " '3\" of snow as of today.' "
3" of snow as of today.
Run Code Online (Sandbox Code Playgroud)
鉴于'...'PowerShell 中的字符串是逐字字符串,'...'如果您不需要字符串插值(例如$(Get-Date)前面示例中的子表达式),则仅可以选择使用 。
从"PowerShell调用外部程序时转义:
作为shell,PowerShell 的工作是将根据其语法规则传递的参数传递给目标可执行文件,以便 PowerShell 解析产生的逐字值以一种使目标可执行文件能够看到它们的方式传递。换句话说:PowerShell 应该在幕后自动执行任何所需的转义。(与 不同的是cmd.exe,PowerShell 不能只按原样传递自己的参数语法,因为外部 CLI 不能理解'...'字符串(单引号)或`转义)。
举个简单的例子:根据最广泛使用的转义约定,传递'3" of snow' 应该"3\" of snow"在幕后传递。
遗憾的是,直到 PowerShell 7.2.x 为止,情况并非如此,外部程序参数中的嵌入字符必须另外手动转义"\才能正确传递。
$PSNativeCommandArgumentPassing选项变量# Broken behavior up to PS v7.2.x
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
Run Code Online (Sandbox Code Playgroud)
这个错误自 v1 以来就存在,并且从未被修复,以避免破坏现有的解决方法。
[1] 在 PowerShell 内部,"..."仅在字符串中,您还可以使用""转义嵌入的",作为替代`"
反引号在 Powershell 中`用作转义字符。也就是说,转义引号、制表符等等。与许多其他环境不同,Powershell 的换行符是`n, 而不是\n。这样做的好处是可以简化路径,因为这些路径在 Windows 中使用反斜杠。
作为一个实际的例子,在许多编程语言中,需要转义路径中的反斜杠。如果您的应用程序位于
c:\program files\newApplication\myApp.exe
Run Code Online (Sandbox Code Playgroud)
它的路径必须写成
c:\\program files\\newApplication\\myApp.exe
Run Code Online (Sandbox Code Playgroud)
双反斜杠表示法意味着实际上存在反斜杠,而不是诸如制表符或换行符之类的元字符。请注意,该路径包含\newApplication. 现在,\n通常意味着换行,但显然情况并非如此。该文件不驻留在
c:\program files\
ewApplication\myApp.exe
Run Code Online (Sandbox Code Playgroud)
毕竟,不是吗?
Powershell 中不需要转义,因为反斜杠本身没有特殊含义。当Powershell看到 时c:\program files\newApplication\myApp.exe,它并没有为上述\n部分赋予任何特殊含义,它只是一个字符串文字。
反斜杠\用作正则表达式中的转义字符并表示元字符。也就是说,要匹配*正则表达式中的文字,必须对其进行转义,以免它表示 Kleene 星号(零个或多个匹配)。