Код выхода из пакетного файла не распространяется на родительский сценарий PowerShell - PullRequest
1 голос
/ 22 марта 2019

Пожалуйста, обратите внимание:

c: \ temp \ 1.cmd

@echo off
setlocal

cmd /c dir aaa
IF %ERRORLEVEL% NEQ 0 GOTO fail
GOTO end
:fail
echo - Script failed

:end
endlocal

Теперь, если я запускаю его в командной строке:

C:\temp> cmd
Microsoft Windows [Version 10.0.16299.967]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\temp>c:\temp\1.cmd
 Volume in drive C has no label.
 Volume Serial Number is 4A5E-F223

 Directory of C:\temp

File Not Found
- Script failed

C:\temp>echo %errorlevel%
1

C:\temp>

Теперь я запускаю его из Powershell:

C:\temp> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.16299.967
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.16299.967
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


C:\temp> cmd /c C:\temp\1.cmd
 Volume in drive C has no label.
 Volume Serial Number is 4A5E-F223

 Directory of C:\temp

File Not Found
- Script failed
C:\temp> $LASTEXITCODE
0
C:\temp>

Из того, что я знаю, код выхода должен распространяться правильно.Итак, в чем проблема?

Ответы [ 2 ]

3 голосов
/ 22 марта 2019

В дополнение к эффективному решению jazzdelightsme с некоторой справочной информацией :

  • После выполнения пакетного файла %ERRORLEVEL% отражаеткод завершения этого пакетного файла - неявный или явный - в том же cmd.exe процессе , который выполнил пакетный файл.

    • An неявный код выхода - это тот, который устанавливается последним оператором сообщения о коде выхода, выполненным до выхода из пакетного файла.

    • An явный код выхода устанавливается путем вызова exit /b <n> в пакетном файле, чтобы выйти из него с указанным кодом выхода (<n>).

  • Процесс cmd.exe, который запускает пакетный файл (всегда в процессе), распространяет только явный код завершения пакетного файла как егокод завершения процесса , т. е. только в том случае, если использованный командный файл exit /b.

    • help exit сформулирован несколько странно (и смешно тоже!«указывает числовое число»), но может быть интерпретирован для передачи этого факта.

    • Возможно, Идея заключалась в том, что неявный код выхода, который несколько случайно установлен, не гарантирует распространение как общий показатель успеха / неудачи во внешний мир.

Вышеприведенное объясняет поведение, которое вы видели:

  • При запуске из cmd.exe этот процесс, который запускал пакетный файл в процессе, видел неявный код завершения пакетного файла в %ERRORLEVEL%

  • В отличие от этого PowerShell должен запускать пакетные файлы в cmd.exe дочернем процессе , поэтому он видит только собственный код выхода cmd.exe, который, как указано,не отражает неявный код выхода.

    • Запуск c:\temp\1.cmd из PowerShell эквивалентен запуску cmd /c c:\temp\1.cmd из cmd.exe - выможет наблюдать одинаковое поведение кода выхода в обоих.
1 голос
/ 22 марта 2019

Первый: ERRORLEVEL не%% ERRORLEVEL% .

Во-вторых, уровень ошибки не совпадает с кодом завершения процесса.

Попробуйте изменить скрипт cmd следующим образом (обратите внимание на добавление «exit / b 1»):

@echo off
setlocal

cmd /c dir aaa
IF %ERRORLEVEL% NEQ 0 GOTO fail
GOTO end
:fail
echo - Script failed
exit /b 1

:end
endlocal
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...