Выход из партии с EXIT/B X, где X >= 1 действует так, как будто команда успешно завершена при использовании && или || операторы между пакетными вызовами

Я пытаюсь связать ряд .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

C:\>

Использование 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

C:\>

Как я могу выйти из a.bat, чтобы a.bat && b.bat и a.bat || b.bat вели себя как ожидалось?

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

Ответы

Ответ 1

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

@%COMSPEC% /C exit 1 >nul

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

Ответ 2

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

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

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

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

C:\>

Кстати, он неправильно говорит о http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/call.mspx?mfr=true:

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

Ответ 3

Если вы используете start/wait, вы также можете использовать это в очень простом приложении для Win, которое вызывается пакетными файлами 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

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

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

Ответ 4

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