Другое

Руководство по последовательному выполнению batch‑скриптов

Узнайте, как правильно последовательно запускать несколько .BAT файлов с помощью команды call, включая обработку ошибок, логирование и лучшие практики для мастер‑скриптов Windows.

Как выполнить несколько файлов .BAT последовательно в скрипте Windows batch?

Я пытаюсь создать основной batch-файл под названием commit-build.bat, который будет последовательно запускать другие batch-файлы в рамках нашего процесса сборки. Текущее содержимое моего основного скрипта выглядит так:

"msbuild.bat"
"unit-tests.bat"
"deploy.bat"

Однако при запуске выполняется только первый файл (msbuild.bat), а остальные игнорируются. Я проверил, что каждый из этих batch-файлов работает корректно, когда запускается отдельно. Какой правильный синтаксис, чтобы все batch-файлы выполнялись в порядке следования внутри основного скрипта?

Правильный синтаксис для последовательного выполнения нескольких файлов .BAT в пакетном скрипте Windows требует использования команды call перед каждым именем файла .BAT. В вашем текущем подходе выполняется только первый скрипт, потому что пакетные файлы завершаются после выполнения без команды call.

Вот исправленная версия вашего commit-build.bat:

batch
call msbuild.bat
call unit-tests.bat
call deploy.bat

Команда call сообщает процессору пакетов выполнить указанный пакетный файл, а затем вернуться к основному скрипту и продолжить выполнение следующей команды. Без неё процессор пакетов выполнит msbuild.bat и никогда не вернётся, фактически игнорируя оставшиеся команды.


Содержание


Понимание команды call

Команда call необходима для последовательного выполнения пакетных файлов в скриптах Windows. Когда вы запускаете пакетный файл напрямую (без call), исходный скрипт ожидает завершения вызванного скрипта, но не сохраняет контекст должным образом.

Ключевые различия:

  • Без call: Скрипт выполняется и завершается, не возвращаясь к мастер‑скрипту
  • С call: Скрипт выполняется, завершается и управление возвращается к мастер‑скрипту

Базовый синтаксис:

batch
call [drive:][path]filename [batch-parameters]

Примеры:

batch
call msbuild.bat
call "C:\scripts\unit-tests.bat"
call "%~dp0deploy.bat"

Кавычки вокруг имён файлов нужны только тогда, когда путь содержит пробелы.


Лучшие практики для мастер‑скриптов

Создание эффективного мастер‑скрипта включает несколько рекомендаций:

1. Используйте абсолютные или относительные пути

batch
call scripts\msbuild.bat
call ..\tests\unit-tests.bat
call "%~dp0deploy.bat"

2. Добавьте логирование и сообщения о статусе

batch
@echo Starting build process...
call msbuild.bat
if %ERRORLEVEL% neq 0 (
    echo Build failed!
    exit /b 1
)

echo Running unit tests...
call unit-tests.bat
if %ERRORLEVEL% neq 0 (
    echo Unit tests failed!
    exit /b 1
)

echo Deploying application...
call deploy.bat
if %ERRORLEVEL% neq 0 (
    echo Deployment failed!
    exit /b 1
)

echo All operations completed successfully!

3. Установите правильную среду

batch
@echo off
setlocal enabledelayedexpansion
title Build Process

Обработка ошибок и логирование

Надёжные пакетные скрипты должны включать надёжную обработку ошибок и логирование:

Базовая проверка ошибок

batch
@echo off

echo Starting build process...

call msbuild.bat
if %ERRORLEVEL% neq 0 (
    echo ERROR: msbuild.bat failed with error code %ERRORLEVEL%
    exit /b %ERRORLEVEL%
)

echo msbuild.bat completed successfully.

call unit-tests.bat
if %ERRORLEVEL% neq 0 (
    echo ERROR: unit-tests.bat failed with error code %ERRORLEVEL%
    exit /b %ERRORLEVEL%
)

echo unit-tests.bat completed successfully.

call deploy.bat
if %ERRORLEVEL% neq 0 (
    echo ERROR: deploy.bat failed with error code %ERRORLEVEL%
    exit /b %ERRORLEVEL%
)

echo deploy.bat completed successfully.
echo Build process completed successfully!

Расширенное логирование

batch
@echo off
set LOGFILE=build_%DATE:~-4,4%%DATE:~-7,2%%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%.log

echo Build started at %DATE% %TIME% > %LOGFILE%
echo. >> %LOGFILE%

call msbuild.bat 2>&1 | tee -a %LOGFILE%
if %ERRORLEVEL% neq 0 (
    echo ERROR: msbuild.bat failed! See %LOGFILE% for details.
    exit /b %ERRORLEVEL%
)

call unit-tests.bat 2>&1 | tee -a %LOGFILE%
if %ERRORLEVEL% neq 0 (
    echo ERROR: unit-tests.bat failed! See %LOGFILE% for details.
    exit /b %ERRORLEVEL%
)

call deploy.bat 2>&1 | tee -a %LOGFILE%
if %ERRORLEVEL% neq 0 (
    echo ERROR: deploy.bat failed! See %LOGFILE% for details.
    exit /b %ERRORLEVEL%
)

echo All operations completed successfully! >> %LOGFILE%
echo Build completed successfully! See %LOGFILE% for details.

Работа с разными каталогами

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

Метод текущего каталога

batch
@echo off
setlocal

call msbuild.bat

cd /d "%~dp0"
call scripts\unit-tests.bat

cd /d "%~dp0"
call deploy\deploy.bat

echo All scripts executed successfully.

Метод pushd/popd

batch
@echo off
setlocal

call msbuild.bat

pushd "%~dp0scripts"
call unit-tests.bat
popd

pushd "%~dp0deploy"
call deploy.bat
popd

echo All scripts executed successfully.

Полный пример мастер‑скрипта

Ниже приведён полный пример commit-build.bat со всеми лучшими практиками:

batch
@echo off
setlocal enabledelayedexpansion
title Build Process

:: Установить файл логов с временной меткой
set LOGFILE=build_%DATE:~-4,4%%DATE:~-7,2%%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%.log
set LOGDIR=%~dp0logs

:: Создать каталог логов, если он не существует
if not exist "%LOGDIR%" mkdir "%LOGDIR%"

:: Инициализировать лог
echo Build Process Started: %DATE% %TIME% > "%LOGDIR%\%LOGFILE%"
echo Build Master Script: %~nx0 >> "%LOGDIR%\%LOGFILE%"
echo. >> "%LOGDIR%\%LOGFILE%"

:: Выполнить скрипт сборки
echo Executing msbuild.bat...
call msbuild.bat
if %ERRORLEVEL% neq 0 (
    echo ERROR: msbuild.bat failed with error code %ERRORLEVEL%
    echo ERROR: msbuild.bat failed with error code %ERRORLEVEL% >> "%LOGDIR%\%LOGFILE%"
    exit /b %ERRORLEVEL%
)
echo msbuild.bat completed successfully. >> "%LOGDIR%\%LOGFILE%"

:: Выполнить unit‑тесты
echo Executing unit-tests.bat...
call unit-tests.bat
if %ERRORLEVEL% neq 0 (
    echo ERROR: unit-tests.bat failed with error code %ERRORLEVEL%
    echo ERROR: unit-tests.bat failed with error code %ERRORLEVEL% >> "%LOGDIR%\%LOGFILE%"
    exit /b %ERRORLEVEL%
)
echo unit-tests.bat completed successfully. >> "%LOGDIR%\%LOGFILE%"

:: Выполнить деплой
echo Executing deploy.bat...
call deploy.bat
if %ERRORLEVEL% neq 0 (
    echo ERROR: deploy.bat failed with error code %ERRORLEVEL%
    echo ERROR: deploy.bat failed with error code %ERRORLEVEL% >> "%LOGDIR%\%LOGFILE%"
    exit /b %ERRORLEVEL%
)
echo deploy.bat completed successfully. >> "%LOGDIR%\%LOGFILE%"

:: Завершить процесс сборки
echo. >> "%LOGDIR%\%LOGFILE%"
echo Build Process Completed: %DATE% %TIME% >> "%LOGDIR%\%LOGFILE%"

echo Build process completed successfully!
echo Log file created at: "%LOGDIR%\%LOGFILE%"
endlocal

Частые советы по устранению неполадок

1. Ошибки «Файл не найден»

Если вы видите ошибки «file not found»:

  • Проверьте, что пути к файлам корректны
  • Используйте %~dp0 для ссылки на каталог скрипта
  • Убедитесь, что в названиях файлов нет опечаток

2. Скрипт останавливается

Если скрипты перестают выполняться:

  • Убедитесь, что перед каждым пакетным файлом используется call
  • Проверьте, не содержат ли скрипты команды exit или exit /b без надлежащей обработки ошибок
  • Убедитесь, что в предыдущих скриптах нет бесконечных циклов

3. Проблемы с рабочим каталогом

Если скрипты не могут найти файлы:

  • Используйте cd /d для смены каталогов между скриптами
  • Используйте абсолютные пути для всех операций с файлами
  • Рассмотрите возможность использования pushd и popd для управления каталогами

4. Переменные окружения

Если переменные окружения не работают:

  • Правильно используйте setlocal и endlocal
  • При сложной работе с переменными рассмотрите setlocal enabledelayedexpansion

5. Советы по отладке

Добавьте информацию об отладке:

batch
@echo on  :: Показать все выполняемые команды
echo Current directory: %CD%
echo Error level: %ERRORLEVEL%

Помните, что надёжная обработка ошибок и логирование критически важны для продакшн‑скриптов, так как они помогают быстро выявлять и устранять проблемы при автоматизированных сборках.

Авторы
Проверено модерацией
Модерация