Выход из партии с 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.