Выход из пакета с `EXIT / BX`, где X> = 1, действует так, как будто команда успешно выполнена при использовании && или ||операторы между пакетными вызовами - PullRequest
17 голосов
/ 08 января 2011

Я пытаюсь объединить последовательность файлов .bat с помощью команды EXIT /B X для возврата успеха или неудачи и && и || для условного запуска следующего .bat (например, a.bat && b.bat).

Независимо от того, позвоню ли я EXIT /B 0 или как-нибудь еще, чтобы закончить a.bat, a.bat && b.bat позже вызовет b.bat. Насколько я понимаю, EXIT /B 0 должен установить ERRORLEVEL=0, что является успехом, поэтому && следует продолжить. В противоположность этому, вызов EXIT /B 1 должен установить ERRORLEVEL=1, что является ошибкой, поэтому && должен прекратиться. Что мне здесь не хватает?

Тривиальный пример:

Для не пакетных команд, действующих как ожидалось:

C:\> echo test|findstr test>NUL && echo yes
yes

C:\> echo test|findstr test>NUL || echo yes

C:\> echo test|findstr nope>NUL && echo yes

C:\> echo test|findstr nope>NUL || echo yes
yes

Использование EXIT /B всегда считает a.bat успешным:

C:\> echo @EXIT /B 0 > a.bat

C:\> a.bat && echo yes
yes

C:\> a.bat || echo yes

C:\> echo @EXIT /B 1 > a.bat

C:\> a.bat && echo yes
yes

C:\> a.bat || echo yes

Как выйти из a.bat, чтобы a.bat && b.bat и a.bat || b.bat вели себя как положено?

Все команды выполняются в cmd.exe в Windows XP SP3.

Ответы [ 4 ]

13 голосов
/ 09 января 2011

Если вы спросите меня, коды выхода в пакетных файлах не работают именно по этой причине, но есть обходной обходной путь, который вы можете использовать. В качестве последней строки вашего пакетного файла используйте:

@%COMSPEC% /C exit 1 >nul

Поскольку это фактический процесс, который запускается, вы получаете реальный код завершения процесса, а && и || будет работать.

11 голосов
/ 08 января 2011

Работает так, как должно при использовании call для выполнения пакетных сценариев, содержащих инструкцию выхода:

C:\>echo @EXIT /B 1 > a.bat

C:\>call a.bat && echo yes

C:\>call a.bat || echo yes
yes

Кстати, там написано неправильно на Документы Microsoft :

Вызов не действует в командной строке когда он используется вне сценария или пакета файл.

0 голосов
/ 28 сентября 2017

Я думаю, что вы получаете Errorlevel=0, потому что вы действительно выполняете a.bat (независимо от кода возврата).

Вы бы провалили проверку, если бы a.bat не существовало. CALL - единственный известный мне способ извлечения окружающей среды из a.bat.

0 голосов
/ 14 ноября 2013

Если вы используете start /wait, вы также можете использовать это в очень простом приложении Windows (написанном на C #), которое называется пакетными файлами DOS, например:

static class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        Environment.ExitCode = Convert.ToInt32(args[0]);
    }
}

Тогда приложение может вызыватьсяПакетный файл DOS и оцените результат.то есть

c:> start /wait SetRC 1
c:> if "%errorlevel%"=="1" goto abort

ПРИМЕЧАНИЕ: /wait не требуется в пакетном файле.

Вы можете передать желаемый код возврата в качестве аргумента в свой program.cs и получить еготаким образом гарантировано.

...