powershell 指示错误的退出代码
wrong exit code indicated by powershell
我有大量遗留的 cmd 脚本,用作我们使用的某些软件设置的一部分。从 cmd 和 powershell 脚本调用脚本。有时它会失败,这由退出代码指示。该脚本的问题是它创建了很多环境变量并且不能很好地处理它们,因此如果在同一环境中两次 运行,第二次执行可能无法按预期工作。只有当它是 cmd
的 运行 时才是问题,Powershell 总是在子 shell 中启动 cmd 脚本,所以这不是问题。
现在,我通过在子 shell 中强制它 运行 来快速修复它(因此当脚本终止时,子 shell 也终止,我们最终在一个干净的环境中准备 运行再次脚本)。 "Fix" 看起来像这样:
@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
。命令脚本:
@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
瓦特???现在更有趣的部分是:如果我从原始脚本中删除 goto :eof
,它就会开始按预期工作(我在调试后不小心把它留在那里了)。但它甚至不应该在它之前的 if
的两个分支退出脚本时执行。我错过了什么?为什么我看到的是我看到的?
我目前使用 Windows 10,但我在 Windows Server 2012、Windows Server 2012 R2 和 Windows 8 上看到了相同的行为,所以我相信它是不 OS 依赖。
看起来像 cmd
错误。让我们有这个 Test.cmd
文件:
@(
exit /b 1
rem
)
现在在命令行中输入以下命令:
> Test.cmd
> echo %errorlevel%
1
> cmd /c Test.cmd
> echo %errorlevel%
0
如您所见,如果您在子 shell 中 运行 此 .cmd
文件,则错误级别设置不正确。
我有大量遗留的 cmd 脚本,用作我们使用的某些软件设置的一部分。从 cmd 和 powershell 脚本调用脚本。有时它会失败,这由退出代码指示。该脚本的问题是它创建了很多环境变量并且不能很好地处理它们,因此如果在同一环境中两次 运行,第二次执行可能无法按预期工作。只有当它是 cmd
的 运行 时才是问题,Powershell 总是在子 shell 中启动 cmd 脚本,所以这不是问题。
现在,我通过在子 shell 中强制它 运行 来快速修复它(因此当脚本终止时,子 shell 也终止,我们最终在一个干净的环境中准备 运行再次脚本)。 "Fix" 看起来像这样:
@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
。命令脚本:
@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
瓦特???现在更有趣的部分是:如果我从原始脚本中删除 goto :eof
,它就会开始按预期工作(我在调试后不小心把它留在那里了)。但它甚至不应该在它之前的 if
的两个分支退出脚本时执行。我错过了什么?为什么我看到的是我看到的?
我目前使用 Windows 10,但我在 Windows Server 2012、Windows Server 2012 R2 和 Windows 8 上看到了相同的行为,所以我相信它是不 OS 依赖。
看起来像 cmd
错误。让我们有这个 Test.cmd
文件:
@(
exit /b 1
rem
)
现在在命令行中输入以下命令:
> Test.cmd
> echo %errorlevel%
1
> cmd /c Test.cmd
> echo %errorlevel%
0
如您所见,如果您在子 shell 中 运行 此 .cmd
文件,则错误级别设置不正确。