使用正确的退出代码报告从PowerShell调用批处理文件,同时避免插入符号加倍 [英] Call a batch file from PowerShell with proper exit code reporting while avoiding doubling of carets
问题描述
我怀疑没有好的解决方案,但是也许我忽略了一些东西:
I suspect there is no good solution, but perhaps I'm overlooking something:
我追求的是一种方法:
-
(a)以某种方式从PowerShell调用批处理文件,该方式使稳健反映其在PowerShell的自动
$ LASTEXITCODE
变量中的-隐式或显式-退出代码.
(a) call a batch file from PowerShell in a way that robustly reflects its - implicit or explicit - exit code in PowerShell's automatic
$LASTEXITCODE
variable.
-
值得注意的是,调用以
whoami -nosuch ||退出的批处理文件.退出/b
,应导致$ LASTEXITCODE
反映whoami
的退出代码,即1
.当您从PowerShell调用批处理文件(按名称或路径)时,情况不是 :退出代码为0
(相反,在cmd内部).exe
会话%ERRORLEVEL%
设置为1
).
Notably, calling a batch file that exits with, say,
whoami -nosuch || exit /b
, should result in$LASTEXITCODE
reflectingwhoami
's exit code, i.e.1
. This is not the case when you invoke a batch file (by name or path) from PowerShell: the exit code is0
(by contrast, inside acmd.exe
session%ERRORLEVEL%
is set to1
).
还请注意,调用应与PowerShell的输出流保持集成,因此,我不在寻找基于
Also note that the invocation should remain integrated with PowerShell's output streams, so I am not looking for solutions based on System.Diagnostics.Process
.
此外,我还不了解或控制要调用的批处理文件-我正在寻找通用的解决方案.
Furthermore, I have no knowledge of or control over the batch files getting invoked - I'm looking for a generic solution.
(b)不会以任何方式更改传递给批处理文件的双引号参数,并且不会以任何方式修改 cmd.exe
的行为;值得注意的是:
(b) without double-quoted arguments passed to the batch file getting altered in any way, and without cmd.exe
's behavior getting modified in any way; notably:
-
^
字符应该不加倍(见下文). - 使用
/V:ON
启用延迟扩展是 not 的一种选择.
^
characters should not be doubled (see below).- Enabling delayed expansion with
/V:ON
is not an option.
我唯一知道解决方法(a)的方法是通过 cmd/c调用
调用批处理文件.
The only way I know how to solve (a) is to invoke the batch file via cmd /c call
.
不幸的是,这违反了要求(b),因为使用 call
似乎总是将参数中的 ^
字符加倍.(而且,相反,使用 call
not 则不能可靠地报告退出代码.)
Unfortunately, this violates requirement (b), because the use of call
seemingly invariably doubles ^
characters in arguments. (And, conversely, not using call
then doesn't report the exit code reliably).
有没有办法满足两个条件?
Is there a way to satisfy both requirements?
请注意,PowerShell仅是这里的使者:问题出在 cmd.exe
上,任何从 cmd.exe
会话外部调用批处理文件的人都面临着同样的问题.
Note that PowerShell is only the messenger here: The problem lies with cmd.exe
, and anyone calling a batch file from outside a cmd.exe
session is faced with the same problem.
示例(PowerShell代码):
Example (PowerShell code):
# Create a (temporary) batch file that echoes its arguments,
# provokes an error, and exits with `exit /b` *without an explicit argument*.
'@echo off & echo [%*] & whoami -nosuch 2>NUL || exit /b' | Set-Content test.cmd
# Invoke the batch file and report the exit code.
.\test.cmd "a ^ 2"; $LASTEXITCODE
输出应该是:
The output should be:
["a ^ 2"]
1
但是,实际上没有报告退出代码:
However, in reality the exit code is not reported:
["a ^ 2"]
0 # !! BROKEN
如果我改用 cmd/c call.\ test.cmd
进行调用,则退出代码正确,但是 ^
字符加倍:
If I call with cmd /c call .\test.cmd
instead, the exit code is correct, but the ^
characters are doubled:
PS> cmd /c call .\test.cmd "a ^ 2"; $LASTEXITCODE
["a ^^ 2"] # !! BROKEN
1 # OK
推荐答案
我不知道为什么会这样,但确实如此:
I've no idea why this works, but it does:
cmd /c '.\test.cmd "a ^ 2" & exit'
$LASTEXITCODE
输出:
["a ^ 2"]
1
这篇关于使用正确的退出代码报告从PowerShell调用批处理文件,同时避免插入符号加倍的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!