powershell指示错误的退出代码

时间:2015-11-02 22:50:12

标签: powershell cmd exit-code

我有一个巨大的遗留cmd脚本,用作我们使用的某些软件设置的一部分。从cmd和powershell脚本调用脚本。有时它会失败,退出代码表示。该脚本的问题是它创建了许多环境变量并且不能很好地处理它们,因此如果在同一环境中运行两次,则第二次执行可能无法按预期工作。只有当它从cmd运行时才会出现问题,Powershell总是在子shell中启动cmd脚本,所以不存在问题。

现在,我通过强制它在子shell中运行来快速修复它(因此当脚本终止时,子shell也会终止,并且我们最终会在一个干净的环境中准备再次运行脚本)。 "修正"看起来像这样:

@echo off

if "%running_in_subshell%"=="" (
    set running_in_subshell=1
    cmd /c %0
    if errorlevel 1 (
        set running_in_subshell=
        echo fail
        exit /b 1
    ) else (
        set running_in_subshell=
        echo success
        exit /b 0
    )
    goto :eof
)

rem lot of weird old code noone wants to touch here, now run in a subshell

echo exiting with error, subshell: %running_in_subshell%

rem it does not always exits with "1", but for the sake of this question let return error always
exit 1

有趣的部分现在开始。修复完成后,调用它的Powershell脚本开始出现检测失败的问题。假设,我们将上面的脚本保存为a.cmd。 Cmd脚本:

@echo off
call a.cmd
if errorlevel 1 (
    echo ^>^> script failed
) else (
    echo ^>^> script succeeded
)

产生以下输出:

exiting with error, subshell: 1
fail
>> script failed

这是预期的,但是PowerShell脚本:

.\a.cmd
if ($lastexitcode -gt 0)
{
    write-output ">> script failed"
} 
else
{
    write-output ">> script succeeded"
}

产生

exiting with error, subshell: 1
fail
>> script succeeded

WAT ???现在更有趣的部分:如果我从原始脚本中删除goto :eof,它会按预期开始工作(我在调试后意外地将它留在那里)。但它甚至不应该执行,因为它前面的if的两个分支都退出脚本。我错过了什么?为什么我会看到我看到的内容?

我目前使用的是Windows 10,但我在Windows Server 2012,Windows Server 2012 R2和Windows 8上看到了相同的行为,因此我认为它不依赖于操作系统。

1 个答案:

答案 0 :(得分:3)

看起来像if (strpos($_GET['link'], ".") !== false) { $parts = explode(".",$_GET['link']); $link = $parts[0]; }else{ $link = $_GET['link']; } include($_SERVER['DOCUMENT_ROOT'].'/files/'.$link.'.php'); 错误。我们有这个cmd文件:

Test.cmd

现在在命令行中输入以下命令:

@(
    exit /b 1
    rem
)

如您所见,如果您在子shell中运行此> Test.cmd > echo %errorlevel% 1 > cmd /c Test.cmd > echo %errorlevel% 0 文件,则未正确设置错误级别。