Команда CHOICE выводит в командной строке меню из одной или нескольких клавиш-вариантов и ожидает нажатия. Результат выбора сохраняется в переменной ERRORLEVEL, которую bat-скрипт использует для ветвления — это основа любого интерактивного сценария автоматизации в CMD.
Синтаксис команды 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.
Частые вопросы
Почему 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.