在Powershell中转义和(&)符号

s5a0g9ez  于 2022-12-26  发布在  Shell
关注(0)|答案(1)|浏览(283)

我需要在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或user-agent)包含&字符,则会失败。
示例:powershell c:\ffmpeg -headers 'Cookies: param=a=1&b=2; session=123'
如何在一行程序中“转义”&字符?
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表示
必须指定输入文件
但是输入文件是在-i参数之后指定的。
此命令有什么问题?

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

46scxncf1#

当从cmd.exe调用时,事情变得棘手;下面是一个简化示例:

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

简而言之:cmd.exe/批处理文件中,在传递给-Command-c*[1]的整个"..."字符串中传递PowerShell的CLI应视为双引号参数 * 的内容(这是powershell.exe的 * 默认 * 参数):

  • 注:
      • \"...\"通常是转义的 * 首选 * 形式,因为它适用于 * 两个 * PowerShell版本,并且与 * 大多数 * CLI期望"转义的方式一致;但是,当从cmd.exe调用时,它并不适用于 * 所有 * 情况,例如下面的情况。

相比之下,\"...\" * 总是 * 安全地用于 * 非shell上下文*,例如任务计划程序和Windows Run对话框(WinKey-R)。

  • 同时处理从cmd.exe/批处理文件调用PowerShell CLI的所有 * 边缘情况 *(即当要引用的字符串包含cmd.exe * 元字符 *(如&)时,如您的情况),请使用以下内容代替\"...\"
  • 调用*Windows PowerShell***(powershell.exe)时:使用"^""..."^""**(原文如此)
  • 调用*PowerShell(核心)v6 +*pwsh.exe)时:使用""...""

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

    • PowerShell * 的命令行最好通过参数-c-Command的缩写,在 * Windows PowerShell * 中为默认值,但在PowerShell(Core)v6+中已更改,现在默认为-File)以 * 单个 *、"..."括起的字符串形式传递。
  • 由于PowerShell CLI在命令行解析 * 期间,* 在 * 将结果解释为PowerShell代码之前 * 剥离 * 未转义的 * "字符,因此要保留 * 作为最终执行 * 的命令的一部分的任何**"示例必须 * 转义***(注意PowerShell-* 内部 * ``"用于转义";或者仅在"..."串的上下文中,可使用""`)。
  • "..."-c总参数中的**"^""..."^""(* Windows PowerShell )和""..."" PowerShell(Core)v6 +*)可确保cmd.exe本身将...解释为位于双引号字符串中,这是这些转义形式 * 健壮**的原因。
  • 如果\"...\""..."内部从cmd.exe使用(它只将""识别为转义的"),它实际上将把...看作是在双引号字符串的 * 外部 *,这将导致包含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中:

  • 作为一个独立的 * 表达式 *,它会导致 * 语法错误 *(尝试单独执行它);你必须使用('this ' + "is " + 'text')或者使用一个 * 单 * 引号字符串('this is text')。
  • 作为传递给命令(程序)的 * 参数 *,它被解释为 * 3个不同的 * 参数-请参见this answer以了解这种令人惊讶的行为的解释。

[1]使用 * overall * "..."引号将变成 * single * -Command参数的内容括起来在概念上更可取,但不是绝对必要的。如果没有使用 * overall "..."引号,则\"-转义将被视为命令一部分的"字符是唯一支持的形式-请参见this answer

相关问题