Eu tenho um comportamento estranho, definindo o nível de erro em um script em lotes para 0.
Estou chamando um script a.bat
em lote em um trabalho Jenkins, que por sua vez chama um segundo script b.cmd
e avalia o nível de erro após a chamada:
:: b.cmd
:: some stuff, but relevant is only this:
@echo b errorlevel: %errorlevel%
EXIT /B 0
O script "principal":
:: a.bat
pushd %CD%
cd..
@echo a errorlevel: %errorlevel%
set outputdir=".\some\exisiting\dir"
:: (1)
md %outpurdir%
@echo a errorlevel: %errorlevel%
:: (!)
if "$somevar" = "FOO" (
cd .\WhereBIs
:: (2)
call :seterr 0
@echo a errorlevel: %errorlevel%
:: (3)
call b.cmd
@if %errorlevel% neq 0 (
@echo a errorlevel: %errorlevel%
set errmsg=Error calling b
goto error
)
:: more stuff
)
:error
@echo %errmsg%
popd
:: (4)
@echo a errorlevel: %errorlevel%
@if %errorlevel% neq 0 exit %errorlevel%
Exit /B 1
:seterr
exit /b %1
(Eu peguei emprestado o :seterr
material desta pergunta )
O que parece acontecer quando executo o trabalho de Jenkins:
md
retorna e nível de erro está definido como 1, porque o diretório já existe.- a chamada para
:seterr
não tem o efeito esperado, o nível de erro permanece 1 - a chamada para
b.cmd
termina sem problemas, o nível de errob
é 0, mas após a chamada o nível de erro aindaa
é 1, o que eu definitivamente não esperaria depois de ler as respostas da pergunta vinculada. - após o salto
:error
e a chamada depopd
, errorlevel repentinamente é redefinido para 0 - o que eu também não esperaria.
Alguém tem idéia do que pode estar acontecendo aqui? Não defini acidentalmente o nível de erro manualmente, por isso deve ser a variável do sistema, não definida pelo usuário.
windows
command-line
batch
jenkins
windows-error-reporting
Arne Mertz
fonte
fonte
Respostas:
Você não mostrou o script inteiro. A única explicação possível de que tenho conhecimento é que seu código está dentro de um bloco de código entre parênteses maior, possivelmente parte de um loop FOR ou de uma condição IF.
% ERRORLEVEL% é expandido quando a linha é analisada e todo o bloco entre parênteses é analisado ao mesmo tempo. Portanto, o ERRORLEVEL que você está vendo deve ter existido antes do início da parêntese mais externa.
Você deve usar a expansão atrasada se desejar ver um valor alterado dentro de um bloco de código.
Aqui está uma demonstração simples:
-- RESULTADO --
fonte
:: (!)
comentário Thansk para esclarecer o meu erro.!Embora essa solicitação seja resolvida, há outro motivo para um comportamento como o descrito. Por exemplo, coloque isso em um arquivo em lotes e execute-o:
Se você observar a saída deste lote, a linha que começa com 3: estará faltando e a linha que começará com 4: será prejudicial.
Conclusão: Não avalie o nível de erro com% errorlevel%, mas com if errorlevel.
fonte
%ERRORLEVEL%
é a única opção razoável. A conclusão correta é que você nunca deve definir sua própria variável de ambiente ERRORLEVEL, pois ela substitui o valor dinâmico. O mesmo é verdadeiro para as outras variáveis dinâmicas, como pseudo%CD%
,%TIME%
,%DATE%
,%RANDOM%
, etc. Se a variável é definida, em seguida, o comportamento dinâmico é restaurada por retirar definição da variável comset "errorlevel="