在 Powershell 中转义和 (&) 符号

Escaping the and (&) sign in Powershell

我需要在 ffmpeg --header 参数中使用 \r\n。这适用于 Unix,但不适用于 Windows 命令提示符。所以我想知道使用 powershell

powershell c:\ffmpeg -headers 'User-Agent: user-agent'"`r`n"'Cookies: my-cookie' ...

我知道我必须在使用特殊字符时使用 'string'

"`r`n"

作为我的 \r\n 分隔符。

我也测试过可以把它们混合在一起,比如'this '"is "'text'得到this is text

但是,如果我的字符串(cookie 或用户代理)包含 & 个字符,它将失败。

示例:powershell c:\ffmpeg -headers 'Cookies: param=a=1&b=2; session=123'

如何在一行中 "escape" & 个字符?


这些示例(部分被屏蔽)被CMD接受,但它们不起作用

powershell -c "c:\ffplay -user_agent ""Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0"" -headers ""Cookie: nlqptid=h=676886edeea5bae904b0cf53daec8038.1519940538670&hdnea=exp=1519940598~acl=/*~hmac=C0E019502B060D23AB02BB157FCFFC72404500770A2CE5B00789A84AAEFBD77F&nltid=xxxxxxxxxx&nltdt=0&uid=744826&csid=xxxxxxxxxx; hdntl=exp=1520026938~acl=%2f*~hmac=952689e6de57a2a201ddc1d4c0794962fdc886ea48cf41494a42e787ef923bf9`r`n"" -i ""https://xxxxxxxxxx.net/nlds_vod/xxxxxxxxxx/vod/2018/02/28/cd264e10-dd54-3de2-df90-4c1cac104dcb/v1/stream/cd264e10-dd54-3de2-df90-4c1cac104dcb_1_4500_pc.mp4.m3u8"""

powershell -c "c:\ffplay -headers ""User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0`r`nCookie: nlqptid=h=676886edeea5bae904b0cf53daec8038.1519940538670&hdnea=exp=1519940598~acl=/*~hmac=C0E019502B060D23AB02BB157FCFFC72404500770A2CE5B00789A84AAEFBD77F&nltid=xxxxxxxxxx&nltdt=0&uid=744826&csid=xxxxxxxxxx; hdntl=exp=1520026938~acl=%2f*~hmac=952689e6de57a2a201ddc1d4c0794962fdc886ea48cf41494a42e787ef923bf9`r`n"" -i ""https://xxxxxxxxxx.net/nlds_vod/xxxxxxxxxx/vod/2018/02/28/cd264e10-dd54-3de2-df90-4c1cac104dcb/v1/stream/cd264e10-dd54-3de2-df90-4c1cac104dcb_1_4500_pc.mp4.m3u8"""

ffplay

An input file must be specified

但是输入文件是在-i参数后指定的。

这个命令有什么问题?


请注意,该实现是现有批处理脚本的一部分,因此需要使用批处理文件内部的语法。

cmd.exe 调用时,事情变得棘手;这是一个简化的例子:

powershell -c "ffmpeg.exe -h "^""User-Agent: usra`r`nCookies: parm=a=1&b=2; session=1"^"""

简而言之:来自 cmd.exe / 批处理文件,以传递 PowerShell 的 CLI 应视为 double-quoted 参数 的整体 "..." 字符串传递给 -Command (-c):

  • Windows PowerShell (powershell.exe): 使用"^""..."^""(原文如此)

  • PowerShell (Core) v6+ (pwsh.exe): 使用 ""...""

  • 注:

    • 虽然 \"...\"both PowerShell 版本中工作,但它不能 稳健地工作 当从 cmd.exe 调用 时,特别是在手头的情况下,由于要引用的字符串包含 cmd.exe 元字符 例如 & - 见下文。

    • 但是,来自no-shell contexts,例如Task Scheduler和Windows Run 对话框 (WinKey-R),\"...\" 工作稳健 并且可能更可取,因为 edition-agnostic,并与 大多数 CLI 期望 " 字符的方式保持一致。被逃脱。

作为一般要求,文字 % 个字符。必须转义为 %% 以防止它们被解释为 cmd.exe 变量引用的一部分 在批处理文件 中。来自命令提示符things are unfortunately more complicated.


  • PowerShell 命令行最好作为 单个 "..."-封闭字符串,通过参数-c-Command的缩写,在Windows PowerShell中是默认的,但是在 PowerShell (Core) v6+ 中已更改,现在默认为 -File).

  • 由于 PowerShell CLI 在 command-line 解析 期间剥离 未转义 " 个字符, 将结果解释为 PowerShell 代码之前,任何 " 实例将被保留 作为命令的一部分最终执行 必须 escaped (注意 PowerShell-internally `" 用于转义 " ; 或者,仅在 "..." 字符串的上下文中,可以使用 "")。

  • "^""..."^"" (Windows PowerShell) 和 ""..."" ( PowerShell (Core) v6+) 在整个 "..." -c 参数中确保 cmd.exe 本身将 ... 解释为在 double-quoted 字符串中,这就是使这些转义形式 robust.

    的原因
  • 如果 \"...\"cmd.exe"..." 中使用(它只将 "" 识别为转义的 "),它实际上会将 ... 视为 外部 一个 double-quoted 字符串,这将导致包含 cmd.exe 元字符的值,例如 &| 中断命令 。比较 cmd.exe 中的以下调用:

    # OK - prints verbatim: The king of "Rock  &  Roll"
    C:\>powershell.exe -c " 'The king of "^""Rock  &  Roll"^""' "
    C:\>pwsh.exe -c " 'The king of ""Rock  &  Roll""' "
    
    # !! BROKEN - cmd.exe interprets "&" as a metachar.
    C:\>powershell.exe -c " 'The king of \"Rock  &  Roll\"' "
    C:\>pwsh.exe -c " 'The king of \"Rock & Roll\"' "
    
    • 注意:您可以通过^转义此类cmd.exe字符(例如^&),但这需要您仔细分析字符串并确定哪些特定部分 cmd.exe 被视为未加引号。如果输入有误,^ 将保留为字符串的文字部分。 "^"" / "" 方法的优点是您无需担心此类陷阱。

顺便说一句:'this '"is "'text' 并不像 Bash 那样创建一个字符串;在 PowerShell 中:

  • 作为stand-alone表达式,会导致语法错误(尝试自己执行);您必须使用 ('this ' + "is " + 'text') 或使用 引号字符串 ('this is text').

  • 作为传递给命令(程序)的 参数 ,它被解释为 3 个不同的 参数 - 请参阅this answer 以获得对此令人惊讶的行为的解释。