powershell $ lastexitcode在运行批处理文件时不起作用

问题描述 投票:1回答:2

我尝试将bat文件中的exitcode / errorlevel代码放入调用bat文件的powershell脚本中。

虽然%ErrorLevel%为1:

BAT文件

call aCONFIGURATION
for %%f in (.\createData\*.g.sql) do sqlcmd -b -U %UserName% -P %Password% -S %sqlClonedServer% -d %sqlClonedDatabaseName%  -i %%f -r1 1> NUL
echo %ERRORLEVEL%

当我在powershell脚本中

$ lastexitcode总是0但%ErrorLevel%表示1

$build = "c:\my.bat"
$state = & $build
Write-Host $LASTEXITCODE

我正在把这个废话的PowerShell充满了臭虫。

我已阅读这些链接,但由于结果不同,他们没有帮助:

如何修复$ lastexitcode

powershell batch-file
2个回答
2
投票

echo %ERRORLEVEL%只是将错误代码写入stdout,之后批处理文件正常退出。

如果您希望批处理脚本在退出时实际返回错误,请使用exit /b [exitcode]

call aCONFIGURATION
for %%f in (.\createData\*.g.sql) do sqlcmd -b -U %UserName% -P %Password% -S %sqlClonedServer% -d %sqlClonedDatabaseName%  -i %%f -r1 1> NUL
exit /b %ERRORLEVEL%

0
投票

我同意所提供的修复,但我认为更多解释是有帮助的。

在BAT中有2个退出值:ERRORLEVEL和退出代码。大多数情况下,BAT文件都尊重ERRORLEVEL。

从CMD提示符运行时,BAT文件将正确返回非零ERRORLEVEL,而不返回“EXIT / B%ERRORLEVEL%”语句,但返回的退出代码将为0。

问题是,当从PowerShell运行BAT文件时,$ LASTEXITCODE正在使用最后一个退出代码,而不是使用最后一个ERRORLEVEL。我认为BAT文件中的FOR语句设置退出代码为0但不设置ERRORLEVEL。添加“EXIT / B%ERRORLEVEL%”会将退出代码设置为与ERRORLEVEL匹配。

显示FOR将退出代码设置为0的示例:

@ECHO OFF
REM Enable !VAR! expansion
SETLOCAL ENABLEDELAYEDEXPANSION

REM Reset ERRORLEVEL to 0
VERIFY > NUL

REM DIR a file that doesn't exist, 3 times, with all output redirected to NUL
REM If the DIR sets the exit code to non-zero then print FAILED1.
REM If the exit code of the FOR statement is 0 then print PASSED1.
FOR /L %%i IN (1,1,3) DO (
  DIR doesntexist.txt 2>1 > NUL || ECHO FAILED1
  ECHO ERRORLEVEL1 !ERRORLEVEL!
) && ECHO PASSED1

ECHO ERRORLEVEL2 %ERRORLEVEL%
EXIT /B %ERRORLEVEL%

这是一个长期棘手的问题。见:Batch goto loses errorlevel

(我没有足够的声誉评论)


推荐问答