使用正确的退出代码报告从PowerShell调用批处理文件,同时避免插入符号加倍 [英] Call a batch file from PowerShell with proper exit code reporting while avoiding doubling of carets

查看:70
本文介绍了使用正确的退出代码报告从PowerShell调用批处理文件,同时避免插入符号加倍的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怀疑没有好的解决方案,但是也许我忽略了一些东西:

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 reflecting whoami'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 is 0 (by contrast, inside a cmd.exe session %ERRORLEVEL% is set to 1).

还请注意,调用应与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆