我想%*
从批处理脚本转发到 Powershell 脚本,这已经可以正常工作了。唯一的问题是我无法干净地转发带有空格的参数。
示例.bat..
@echo off
set cwd=%~dp0
set argv=%*
powershell -NoProfile -ExecutionPolicy Bypass -Command "& '%cwd%Example.ps1' %argv%"
示例.ps1..
Param(
$Message
)
If (!$Message)
{
$Message = "Hello!!!"
}
Write-Host $Message
我可以做得./Example.bat Oh
很好,打印出来Oh
。但是,./Example.bat "Oh no"
也只能打印出来Oh
。./Example "'Oh no'"
虽然可以工作,但并不干净,因为脚本的使用不再相同,这意味着对它的任何使用都会变得紧密耦合,而这是我不想要的。
在批处理文件中嵌入 PowerShell 命令时,应格外小心地正确转义双引号。将整个 PowerShell 命令括在双引号中后,必须将后续的双引号字符转换
"
为\"
这是更正后的
Example.bat
脚本:不要对我进行转义所经历的额外步骤感到困惑。
set argv=%argv:"=\"%
是唯一强制性的步骤,其他行确保空字符串(无参数)也得到正确处理。用户可能认为使用插入符号
^
就足以转义输入字符串中的特殊字符,如下所示"You ^& ^| ^> ^< ^^ I"
如果用户想要输入不带转义符号的特殊字符,更完整的解决方案如下:
正如 注释 所建议的,我们可以通过为命令提示符解释器转义其他特殊字符来扩展解决方案。我们还可以添加双引号来转义符号。(为了清晰起见,我没有使用该
for
命令)然后,我们可以执行以下操作:
Fabrice SANGA 的有用答案解释了转义字符的必要性
"
。嵌入得%*
很好,并提供了一种通常有效的解决方案,即使用\"
转义。然而,它并不健壮,因为它会破坏包含元字符(如或)的封闭参数
cmd.exe
的解析,例如"..."
cmd.exe
&
|
"you & I"
更新:链接的答案已经更新为尝试提供强大解决方案的替代解决方案,但下面的解决方案更简单。
一个强大的解决方案需要一种不同的 - 模糊的 -转义嵌入
"
字符的形式。,即 as"^""
[sic] 而不是 as\"
powershell.exe
Windows PowerShell CLI;对于pwsh.exe
PowerShell (Core) 7 CLI,请使用""
这是一个强大而精简的解决方案,它同样使用这种转义形式来括住目标
*.ps1
路径,以便'
正确处理带有嵌入字符的路径。另请注意,使用了
%~dpn0.ps1
,这样就无需重复基本文件名了Example
:setlocal
用于确保批处理文件中定义的变量作用域于该文件;默认情况下,它们将被全局定义。向João Mac 的回答致敬,他提醒我们,该
if defined somevar
技术可以作为变量空性/不存在性测试,这比if not %somevar%.==.
退一步来说:
如果您的目的仅仅是调用
*.ps1
带有参数的文件,则最好使用-File
(-f
)CLI参数而不是-Command
(-c
)这样做有两个好处:
它消除了转义的需要,因此大大简化了批处理文件(见下文)。
它可以保护您的参数免受 PowerShell 的潜在有害解释:例如,使用 时
-File
,将按$HOME
原样传递参数,而使用 时,-Command
它将扩展为 PowerShell 的自动$HOME
变量。有关何时使用
-File
vs. 的详细指导-Command
,请参阅此答案。在这种特定情况下,无需使用,
%*
因为目的是仅获取传递给批次的第一个参数,而不是所有参数。我建议的
Example.bat
脚本如下:该解决方案考虑了 Compo 的评论和 SANGA 的转义和空参数观察。
编辑1:
重要的是不要忘记之前所写的内容。该规范是一项提案,旨在服务于各种用途,从标准温度和压力(STP)条件下的使用,到混合战争中的使用。
有一些策略可以在包含特殊字符的文件夹中执行批处理。我使用
pushd
和popd
。因此,代码提案已修改,以符合 Mofi 评论的第一部分。已经是评论的第二部分,使用以下命令行(带提示):
D:\Usuários\Botafogo>
"D:\Temp\teste\botafogo é campeão — desenvolvimento e teste 100% (!) com 'nome feio' e `nome bonito` bênção よろしくお願いいたします。\example.bat"
"Hello world! & Does that work? See the second edition. ;) 😉"
至于用
BAT
文件召唤文件PS1
,我只是尝试按照原始消息请求操作。我只是请求你不要把我当成敌人,而要把我当成一个愿意帮助别人的人。编辑2:
根据 mklement0 的回答来使用
metacharacters
(通过转义"
为)。"^""
我使用了在线翻译。抱歉,我的语言不太流利。
我有点不明白这个练习的目的。
根据我对原始问题的理解,这对我来说似乎“有效”,但我确信它不会对其他一些符号“起作用”,这些符号可能重要也可能不重要,这取决于所提供的参数是否符合建议(,,
Oh
)或是否有望被普遍逐字复制。Oh no
"Oh no"
(我重命名了该
.ps1
文件,因为我希望将所有响应数据都保存在 SO 问题编号下)