Команда CHOICE выводит в командной строке меню из одной или нескольких клавиш-вариантов и ожидает нажатия. Результат выбора сохраняется в переменной ERRORLEVEL, которую bat-скрипт использует для ветвления — это основа любого интерактивного сценария автоматизации в CMD.
- Синтаксис команды CHOICE
- Ключи и параметры
- Примеры использования
- Простой запрос да/нет
- Меню с тремя пунктами
- Таймаут с выбором по умолчанию
- Скрытая подсказка с нестандартными клавишами
- Учёт регистра
- Использование CHOICE в цикле
- Частые ошибки и решения
- Когда применять, а когда нет
- FAQ
- Почему ERRORLEVEL нужно проверять от большего к меньшему?
- Можно ли передать выбор пользователя в переменную?
- Работает ли CHOICE в PowerShell?
- Что произойдёт, если пользователь нажмёт недопустимую клавишу?
- Как сделать меню с более чем 9 пунктами?
Синтаксис команды CHOICE
CHOICE [/C варианты] [/N] [/CS] [/T таймаут /D вариант] [/M текст]
Все параметры необязательны. Без аргументов команда выводит [Y,N]? и ждёт нажатия Y или N.
Ключи и параметры
| Ключ | Описание | Пример |
|---|---|---|
/C варианты | Список допустимых клавиш без разделителей. По умолчанию YN. | /C ABC |
/N | Не выводить список вариантов (скрыть подсказку [A,B,C]?) | /C 123 /N |
/CS | Учитывать регистр. Без этого ключа a и A — одинаковы. | /CS /C aAbB |
/T секунды | Таймаут в секундах. Требует /D. | /T 10 |
/D вариант | Вариант по умолчанию при истечении таймаута. Должен входить в /C. | /T 10 /D Y |
/M текст | Текст подсказки, выводимый перед вариантами. | /M "Продолжить?" |
/? | Краткая справка по команде | CHOICE /? |
ERRORLEVEL после выполнения CHOICE: значение соответствует позиции нажатой клавиши в строке /C (первая = 1, вторая = 2 и т.д.). При ошибке или Ctrl+C — 255.
Примеры использования
Простой запрос да/нет
Базовый вариант: пользователь подтверждает действие нажатием Y или N.
@echo off CHOICE /M "Продолжить установку?" IF ERRORLEVEL 2 GOTO :cancel ECHO Установка продолжается... GOTO :end :cancel ECHO Отменено пользователем. :end
При нажатии Y — ERRORLEVEL = 1, при N — ERRORLEVEL = 2. Проверять нужно с наибольшего значения вниз: IF ERRORLEVEL N срабатывает при N и выше.
Меню с тремя пунктами
Скрипт предлагает выбор из трёх действий; цифры удобнее букв, когда пунктов много.
@echo off CHOICE /C 123 /M "Выберите действие: 1-Установить 2-Удалить 3-Выход" IF ERRORLEVEL 3 GOTO :quit IF ERRORLEVEL 2 GOTO :uninstall IF ERRORLEVEL 1 GOTO :install :install ECHO Запуск установки... GOTO :end :uninstall ECHO Запуск удаления... GOTO :end :quit ECHO Выход. :end
Порядок проверки IF ERRORLEVEL всегда — от большего к меньшему, иначе логика ломается.
Таймаут с выбором по умолчанию
Подходит для скриптов автоматического обслуживания: если за 15 секунд никто не нажал — продолжить автоматически.
@echo off CHOICE /C YN /T 15 /D Y /M "Начать резервное копирование? Авто-ответ через 15 сек" IF ERRORLEVEL 2 GOTO :skip ECHO Запуск бэкапа... GOTO :end :skip ECHO Бэкап пропущен. :end
Таймаут обратного отсчёта отображается в строке вместе с подсказкой.
Скрытая подсказка с нестандартными клавишами
Флаг /N убирает отображение допустимых клавиш — пользователь видит только текст /M.
@echo off CHOICE /C 123 /N /M "Введите уровень сложности (1, 2 или 3): " SET /A level=%ERRORLEVEL% ECHO Выбран уровень: %level%
Полезно, когда меню уже отрисовано заранее командами ECHO, и отдельная подсказка лишняя.
Учёт регистра
По умолчанию CHOICE не различает строчные и прописные буквы. Ключ /CS включает проверку регистра.
CHOICE /CS /C yYnN /M "y=мягко Y=жёстко n/N=отмена: "
Теперь y и Y — разные варианты с разными ERRORLEVEL.
Использование CHOICE в цикле
Циклическое меню — пользователь возвращается к выбору после каждого действия, пока не выберет «Выход».
@echo off :menu CLS ECHO 1 - Показать дату ECHO 2 - Показать время ECHO 3 - Выход CHOICE /C 123 /N /M "Выбор: " IF ERRORLEVEL 3 EXIT /B IF ERRORLEVEL 2 (TIME /T & GOTO :menu) IF ERRORLEVEL 1 (DATE /T & GOTO :menu)
После каждого действия скрипт снова показывает меню, пока не будет выбран вариант 3.
Частые ошибки и решения
| Ошибка / симптом | Причина | Решение |
|---|---|---|
| Неверный переход: всегда выполняется первая ветка | Проверки IF ERRORLEVEL идут по возрастанию (1, 2, 3) | Всегда проверять от большего к меньшему: сначала IF ERRORLEVEL 3, потом 2, потом 1 |
| «CHOICE не является внутренней или внешней командой» | CHOICE отсутствует в Windows XP Home (некоторые редакции) | Использовать SET /P или скопировать choice.exe из другой системы в папку скрипта |
| /T без /D вызывает ошибку синтаксиса | Параметры /T и /D обязаны использоваться вместе | Указывать оба параметра: CHOICE /T 10 /D Y |
| Ввод цифр не работает как ожидается | /C интерпретирует каждый символ как отдельную клавишу, включая цифры | Писать цифры подряд без пробелов: /C 123, не /C 1 2 3 |
| Нажатие Ctrl+C ломает скрипт непредсказуемо | При Ctrl+C ERRORLEVEL устанавливается в 0 или 255 | Добавить проверку IF ERRORLEVEL 255 GOTO :abort перед остальными ветками |
Когда применять, а когда нет
CHOICE подходит для bat-скриптов, где нужна интерактивность без внешних инструментов. Не применяйте её в полностью автоматизированных сценариях (CI/CD, планировщик задач) — там, где никто не будет нажимать клавиши, скрипт зависнет навсегда (если не задан /T). Команда работает только в консольных сеансах: в фоновых службах она непригодна. Аналог в PowerShell — конструкция $answer = Read-Host "Продолжить? (Y/N)" с последующим switch или if.
FAQ
Почему ERRORLEVEL нужно проверять от большего к меньшему?
Оператор IF ERRORLEVEL N в CMD срабатывает, если значение переменной больше или равно N. Если начать с IF ERRORLEVEL 1, это условие истинно и при 1, и при 2, и при 3. Поэтому сначала проверяют наибольшее значение, чтобы более специфичные ветки не перекрывались более общими.
Можно ли передать выбор пользователя в переменную?
Напрямую нет — CHOICE не записывает символ в переменную. Обходной путь: после CHOICE использовать SET /A myvar=%ERRORLEVEL%, чтобы сохранить числовой код выбора.
Работает ли CHOICE в PowerShell?
Да, choice.exe можно вызвать из PowerShell как внешний исполняемый файл. Но проверять результат нужно через $LASTEXITCODE, а не через переменную $ERRORLEVEL PowerShell.
Что произойдёт, если пользователь нажмёт недопустимую клавишу?
Команда CHOICE проигнорирует нажатие и будет ждать допустимого ввода. Никакого сообщения об ошибке не будет — курсор просто останется на той же строке.
Как сделать меню с более чем 9 пунктами?
CHOICE принимает любые буквы и цифры в параметре /C, например /C ABCDEFGHIJ. Ограничений на количество вариантов нет, но ERRORLEVEL всё равно будет числом от 1 до N по позиции символа в строке /C.


