Команда GOTO выполняет безусловный переход к указанной метке внутри пакетного файла (.bat или .cmd). Это основной инструмент управления потоком в скриптах CMD: с её помощью строят циклы, ветвления по условию и досрочный выход из скрипта.
- Синтаксис команды GOTO
- Ключи и параметры
- Примеры использования
- Простой переход к метке
- Цикл с помощью GOTO
- Ветвление по условию
- Имитация функций через CALL и GOTO
- Обработка ошибок через GOTO
- Меню выбора в интерактивном скрипте
- Частые ошибки и решения
- Когда применять, а когда нет
- FAQ
- Работает ли GOTO в PowerShell?
- Чем GOTO :EOF отличается от EXIT /B?
- Можно ли перейти к метке в другом bat-файле?
- Можно ли использовать GOTO внутри цикла FOR?
- Как организовать вложенные «функции» через GOTO?
Синтаксис команды GOTO
GOTO метка GOTO :EOF
Расшифровка:
метка— имя метки, определённой в том же файле строкой:метка. При переходе двоеточие перед именем не указывается.:EOF— специальная встроенная метка конца файла. Позволяет завершить выполнение текущего скрипта или подпрограммы (CALL-блока) без объявления реальной метки. Доступна только при расширенной обработке команд (SETLOCAL ENABLEEXTENSIONS, включена по умолчанию).
Ключи и параметры
У команды GOTO нет ключей. Единственный аргумент — имя метки или :EOF. Несколько правил о метках:
| Правило | Пояснение | Пример |
|---|---|---|
| Объявление метки | Метка объявляется строкой, начинающейся с :. Остаток строки после имени игнорируется — можно добавить комментарий. | :start или :start -- начало цикла |
| Регистр не важен | GOTO нечувствителен к регистру: GOTO Start и GOTO start — одно и то же. | GOTO Start |
| Длина имени метки | CMD распознаёт только первые 8 символов имени метки. Метки :verylongname1 и :verylongname2 будут считаться одинаковыми. | Используйте короткие уникальные имена |
Специальная метка :EOF | Завершает текущий блок CALL или весь скрипт. Не нужно объявлять вручную. | GOTO :EOF |
| GOTO внутри FOR/IF | Переход из скобочного блока (...) команды FOR или IF завершает весь блок. | Избегайте GOTO внутри FOR ( ... ) |
Примеры использования
Простой переход к метке
Нужно пропустить часть кода и перейти прямо к завершению.
@echo off echo Начало скрипта GOTO the_end echo Эта строка никогда не выполнится :the_end echo Конец скрипта
Строка между GOTO the_end и :the_end будет пропущена.
Цикл с помощью GOTO
Вывод чисел от 1 до 5 без команды FOR.
@echo off set i=1 :loop echo %i% set /a i+=1 if %i% leq 5 goto loop echo Конец программы
Скрипт возвращается к метке :loop до тех пор, пока переменная i не превысит 5.
Ветвление по условию
Скрипт должен вести себя по-разному в зависимости от значения переменной.
@echo off set /p choice=Введите Y для продолжения: if /i "%choice%"=="Y" goto continue echo Отменено пользователем. goto :EOF :continue echo Продолжаем выполнение...
Если пользователь не вводит Y, скрипт выводит сообщение и завершается через GOTO :EOF.
Имитация функций через CALL и GOTO
Нужно вынести повторяющийся код в «подпрограмму» внутри одного bat-файла.
@echo off call :printline "Первый вызов" call :printline "Второй вызов" goto :EOF :printline echo ------ %~1 ------ goto :EOF
CALL :printline вызывает блок, начинающийся с метки :printline. GOTO :EOF в конце блока возвращает управление в точку после CALL.
Обработка ошибок через GOTO
При неудачном выполнении команды нужно перейти в раздел обработки ошибки.
@echo off xcopy C:\Source D:\Backup /E /Y if errorlevel 1 goto error echo Копирование завершено успешно. goto :EOF :error echo ОШИБКА: xcopy вернул ненулевой код. Проверьте пути. exit /b 1
Если xcopy завершается с ошибкой, управление переходит к метке :error.
Меню выбора в интерактивном скрипте
Нужно предложить пользователю выбрать действие из списка.
@echo off :menu echo 1 - Резервная копия echo 2 - Очистка temp echo 3 - Выход set /p opt=Ваш выбор: if "%opt%"=="1" goto backup if "%opt%"=="2" goto cleanup if "%opt%"=="3" goto :EOF echo Неверный выбор. goto menu :backup echo Запуск резервного копирования... goto menu :cleanup echo Очистка временных файлов... goto menu
Скрипт возвращается к :menu после каждого действия до выбора пункта 3.
Частые ошибки и решения
| Ошибка / проблема | Причина | Решение |
|---|---|---|
GOTO: метка не найдена | Метка написана с опечаткой или находится в другом файле | Проверить написание метки в объявлении (:метка) и в вызове (GOTO метка). Убедиться, что метка в том же файле. |
| Скрипт уходит в бесконечный цикл | Условие выхода из цикла никогда не выполняется | Добавить счётчик итераций или проверить логику условия в IF. |
| GOTO не работает внутри скобок FOR/IF | CMD завершает весь блок (...) при переходе через GOTO | Переместить GOTO за пределы блока скобок или использовать CALL :подпрограмма. |
| Длинные имена меток конфликтуют | CMD учитывает только первые 8 символов имени метки | Давать меткам уникальные имена в пределах первых 8 символов: :bk_daily и :bk_weekly вместо :backup_daily и :backup_weekly. |
Переход в файле с CRLF не находит метку | Файл сохранён в Unix-формате (LF), CMD не распознаёт строки с метками | Убедиться, что bat-файл сохранён с окончаниями строк CRLF (Windows). |
Когда применять, а когда нет
GOTO уместен в пакетных файлах для организации простого ветвления, имитации функций через CALL :метка и обработки ошибок. Избегайте избыточного использования GOTO в сложных скриптах — «спагетти»-переходы трудно отлаживать. Для полноценных циклов предпочтительнее команда FOR. В PowerShell аналог не нужен: PowerShell поддерживает функции (function), циклы (while, for, foreach) и структурированную обработку ошибок через try/catch — GOTO в PowerShell отсутствует как концепция.
FAQ
Работает ли GOTO в PowerShell?
Нет, GOTO — команда только для cmd.exe и пакетных файлов. PowerShell не поддерживает эту команду. Используйте функции, циклы и конструкции break/continue в PowerShell.
Чем GOTO :EOF отличается от EXIT /B?
Оба завершают текущий пакетный файл или подпрограмму. EXIT /B код дополнительно устанавливает код завершения (ERRORLEVEL), тогда как GOTO :EOF сохраняет текущий ERRORLEVEL без изменений.
Можно ли перейти к метке в другом bat-файле?
Нет, GOTO работает только в пределах одного файла. Для вызова другого bat-файла используйте CALL имя_файла.bat или CALL имя_файла.bat :метка для прямого перехода к метке внутри вызываемого файла.
Можно ли использовать GOTO внутри цикла FOR?
Технически да, но переход из блока скобок FOR (...) do (...) завершит весь блок, что часто приводит к непредсказуемому поведению. Лучше вынести логику с GOTO за пределы блока FOR.
Как организовать вложенные «функции» через GOTO?
Используйте CALL :метка вместо GOTO метка. CALL сохраняет точку возврата, а GOTO :EOF в конце блока возвращает управление. Чистый GOTO не возвращается — это безусловный переход.


