Invoke-Expression(其内置别名为iex)和&, the call operator,用途不同:
在手头的情况下:
您的命令的核心是以下表达式,它返回 字符串
"echo 'helloworld'"(其内容不包括封闭的" - 这只是表示结果字符串作为 PowerShell 字符串文字):
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('ZWNobyAnaGVsbG93b3JsZCc='))
另请注意,由于命令行的解析方式,原始命令中围绕核心表达式的""..."" 被有效地忽略,这就解释了为什么该表达式被执行 而不是被视为字符串的内容。[1]
因此,您的两个命令相当于:
[1] 可选阅读:调用外部程序时 PowerShell 引用问题
注意:
即使从 PowerShell-internal 的角度来看,您通过将 "" 转义为 "" 将它们正确嵌入到整个 "..." 字符串中,额外的 @987654358 转义需要@ 和\ ,以便将它们传递给外部程序,即使该外部程序是通过powershell.exe 调用的另一个PowerShell 实例。
以这个简化的例子为例:
powershell.exe -command " ""hi"" " # !! BROKEN
powershell.exe -command ' "hi" ' # !! BROKEN
在 PowerShell 内部," ""hi"" " 和 ' "hi" ' 计算为包含文字内容 "hi" 的字符串,执行时会打印出 hi。
遗憾的是,PowerShell 将此字符串作为 " "hi" " 传递给 powershell.exe - 请注意 "" 如何变成普通的 " 并且封闭的 单引号 被替换为 double 引号 - 在被新实例解析后有效地导致 hi (因为 " "hi" " 被解析为子字符串 " "、hi 和 @ 的 连接 987654374@),因此 PowerShell 最终会尝试执行名为 hi 的(可能不存在的)命令。
相比之下,如果您设法将嵌入的 " 传递为 \" (原文如此) - 在 满足 PowerShell 自己的转义需求之后 - 该命令按预期工作。
因此,如上所述,您需要结合 PowerShell 内部转义和 for-the-CLI 转义,以便传递嵌入的 ",这样:
- 在整体
"..." 内,每个嵌入的" 必须转义为\""(原文如此)或\`"(原文如此)
- 内部整体
'...'、\" 可以按原样使用。
powershell.exe -command " \""hi\"" " # OK
powershell.exe -command " \`"hi\`" " # OK
powershell.exe -command ' \"hi\" ' # OK
或者,使用 脚本块 代替命令 字符串,这样可以绕过引用问题:
powershell.exe -command { "hi" } # OK, but only works when calling from PS
请注意,脚本块技术仅在从 PowerShell 调用 时有效,而不是从 cmd.exe 调用。
cmd.exe 有自己的报价要求:
值得注意的是,cmd.exe 仅支持 "" 用于嵌入双引号(`" 也不支持);因此,在上述解决方案中,只有
powershell.exe -command " \""hi\"" " 可以从cmd.exe (批处理文件)工作,而无需额外转义。
然而,\"" 的缺点是,\""...\"" 之间的内部空白运行每个都折叠为一个空格。为避免这种情况,请使用\"...\",但cmd.exe 会将\" 实例之间的子字符串视为未引用,如果该子字符串包含诸如| 或&;例如,powershell.exe -command " \"a|b\" ";要解决此问题,您必须单独 ^-转义以下字符:& | < > ^
powershell.exe -command ' "hi" ' 同样脆弱,因为cmd.exe 不将' 识别为字符串分隔符,因此嵌入"..." 之外的任何元字符再次由cmd.exe 本身解释;例如,powershell.exe -command ' "hi" | Measure-Object '
最后,仅使用 cmd.exe 中的 "" 来嵌入 " 有时 可行,但不是可靠;例如,powershell.exe -command " 'Nat ""King"" Cole' " 打印 Nat "King Cole(缺少结尾的 ")。
这似乎已在 PowerShell Core 中得到修复。