Как заставить bat-скрипт ждать нажатия клавиши? Печать
Добавил(а) microsin   

В Windows есть несколько способов остановить скрипт и ждать нажатия клавиши: pause, set /p, choice.

[Команда pause]

Команда pause приостановит работу скрипта и отобразит сообщение "Press any key to continue . . .". Если нажать любую клавишу, то работа скрипта продолжится.

Нажатая комбинация клавиш Ctrl+C позволяет остановить работу скрипта, при этом появится сообщение запроса: "Terminate batch job (Y/N)?". Если в ответ вы введете Y (да), то работа скрипта завершится.

Пример использования:

@echo off
:begin
copy a:*.*
echo Вставьте новый диск в дисковод A
pause
goto begin

[Команда set]

Команда set позволяет приостановить работу скрипта и ждать нажатия клавиши Enter [1], хотя вроде команда предназначена для других целей - управления переменными окружения (см. врезку).

Пример использования:

:loop
@set /p DUMMY=Нажмите клавишу Enter для запуска прошивки...
esptool.py --baud=115200 --port=COM1 erase_flash
esptool.py --baud=115200 --port=COM1 write_flash 0 firmware.bin
@goto loop

Отобразит, установит или удалит переменную окружения cmd.exe.

SET [variable=[string]]

  variable  Указывает имя переменной окружения.
  string     Указывает набор символов для присваивания переменной окружения.

Команда SET без параметров отобразит список переменных текущего окружения.

Если разрешены расширения команд (Command Extensions, они разрешены по умолчанию), то команда SET меняется следующим образом:

Когда команда SET вызывается только с именем переменной, без знака равенства или значения, то она отобразит значение всех переменных, префикс которых совпадает с именем, переданным команде SET. Например:

    SET p

.. отобразит все переменные, имя которых начинается с буквы 'P' или 'p'.

Команда SET установит переменную окружения ERRORLEVEL в 1, если имя переменной не было найдено в текущем окружении.

Команда SET не позволяет использовать символ равенства в имени переменной.

Были добавлены две новые опции:

    SET /A expression
    SET /P variable=[promptString]

Опция /A указывает, что строка справа от знака равенства - вычисляемое числовое выражение. Средство оценки выражений является довольно простым и поддерживает следующие операции, в порядке уменьшения приоритетности:

    ()                  - группирование
    ! ~ -               - унарные операторы
    * / %               - арифметические операторы
    + -                 - арифметические операторы
    << >>               - логический сдвиг
    &                   - побитная операция И (AND)
    ^                   - побитная операция ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR)
    |                   - побитная операция ИЛИ (OR)
    = *= /= %= += -=    - присваивание
      &= ^= |= <<= >>=
    ,                   - разделитель выражения

Если вы используете любой из логических или модульных операторов, то вам нужно будет заключить строку выражения в кавычки. Любые нечисловые строки в выражении рассматриваются как имена переменных среды, значения которых преобразуется в числа перед их использованием. Если имя переменной окружения указано, то в настоящее время не определено в окружении, то эта переменная вычисляется как 0. Это позволяет делать арифметику со значениями переменных окружения среды без необходимости вводить все эти знаки % для получения значений переменных. Если SET/A выполняется из командной строки за командного скрипта, то будет отображено конечное значение выражения. Оператор присваивания требует указания имени переменной в левой части выражения. Числовые значения это десятичные числа, если они не снабжены префиксом 0x для шестнадцатеричных чисел или префиксом 0 для восьмеричных чисел. Таким образом, 0x12 это то же самое значение, что и 18 или 022. Обратите внимание на то, что использование восьмеричных значений может вызвать путаницу: 08 и 09 это недопустимые значения, потому что 8 и 9 не используются для цифр восьмеричных значений.

Опция /P позволит вам установить значение переменной в строку, введенную пользователем. Покажет указанное сообщение приглашения promptString перед чтением строки ввода. Строка promptString может быть пустой.

Подстановка переменных среды была расширена следующим образом:

    %PATH:str1=str2%

Это выражение расширит переменную окружения PATH, подставляя каждое вхождение "str1" в расширенный результат "str2". "str2" может быть пустым, что эффективно удалит все вхождения "str1" из расширенного вывода. "str1" может начинаться со звездочки, и в этом случае она будет совпадать с любыми значениями от начала расширенного вывода первого вхождения оставшейся порции str1.

В выражении можно также указать части строк. Например (10 это смещение от начала, 5 это длина):

    %PATH:~10,5%

Это выражение расширит переменную окружения PATH, и затем использует только 5 символов, которые начинаются с 11-го символа (смещение 10) расширенного результата. Если длина (в этом примере 5) не указана, то по умолчанию будет взята остальная часть значения переменной. Если любое из чисел (смещение или длина) отрицательное, то используемое число является длиной значения переменной среды, добавляемого к указанному смещению или длине. Например:

    %PATH:~-10%

Это выражение извлечет последние 10 символов переменной PATH. Другой пример:

    %PATH:~0,-2%

Это выражение извлечет все символы переменной PATH, кроме последних двух.

И наконец, была добавлена поддержка отложенного расширения переменной окружения. По умолчанию эта поддержка всегда запрещена, но может быть разрешена/запрещена опцией командной строки /V интерпретатора CMD.EXE. См. CMD /?

Отложенное расширение переменной среды полезно для обхода ограничений текущего расширения, которое произойдет при чтении строки текста, а не при её выполнении. Следующий пример демонстрирует проблему немедленного расширения переменной:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "%VAR%" == "after" @echo Если вы это видите, то работает
    )

Это пример никогда не отобразит сообщение echo, поскольку %VAR% в ОБОИХ операторах IF подставляется, когда происходит чтение первого оператора IF, потому что он логически включает тело IF, который является составным оператором. Так что IF внутри составного оператора фактически выполняет сравнение "before" с "after", которые никогда не равны. Аналогично, следующий пример не сработает как ожидалось:

    set LIST=
    for %i in (*) do set LIST=%LIST% %i
    echo %LIST%

Это НЕ будет создавать список файлов в текущем каталоге, но вместо этого просто установит переменную LIST на последний найденный файл. Опять же, это связано с тем, что %LIST% расширяется только один раз, когда считывается инструкция FOR, и в это время переменная LIST пуста. Таким образом, фактический цикл FOR, который мы выполняем:

    for %i in (*) do set LIST= %i

.. что просто установит LIST в последний найденный файл.

Отложенное расширение переменной окружения позволит вам использовать другой символ (восклицательный знак) для расширения переменных среды во время выполнения. Если включено отложенное расширение переменной, то приведенные выше примеры могут быть записаны следующим образом для работы по их назначению:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "!VAR!" == "after" @echo Если вы это видите, то работает
    )
set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST%

Если разрешены Command Extensions, то существует несколько динамических переменных окружения, которые могут быть развернуты, но не отображаются в списке переменных, показываемых командой SET. Эти значения переменных вычисляется динамически при каждом расширении значения переменной. Если пользователь явно определяет переменную с одним из этих имен, то это определение будет переопределять динамически:

%CD%   - расширяется в строку текущей директории.

%DATE% - расширяется в текущую дату с использованием такого же формата, какой использует команда DATE.

%TIME% - расширяется в текущее время в таком же формате, какой использует команда TIME.

%RANDOM% - расширится в случайное десятичное число между 0 и 32767.

%ERRORLEVEL% - расширится в текущее значение ERRORLEVEL.

%CMDEXTVERSION% - расширится в текущий номер версии Command Processor Extensions.

%CMDCMDLINE% - расширится в оригинальную командную строку, которой был запущен Command Processor.

%HIGHESTNUMANODENUMBER% - расширится в самое большоe число NUMA node на этой машине.

[choice]

Пример использования:

@echo off
cls

:loop
echo 1) Тест 1
echo 2) Тест 2
echo 3) Тест 3
echo q) Выход

choice /c:123q /n

if errorlevel 4 goto exit
if errorlevel 3 goto метка3
if errorlevel 2 goto метка2
if errorlevel 1 goto метка1
:метка1 действия1
goto loop
:метка2 действия2
goto loop
:метка3 действия3
goto loop
:exit

CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text]

Описание:

    Эта команда дает возможность пользователям выбрать один вариант действия из нескольких предложенных, и возвратить индекс сделанного выбора.

Список параметров:

   /C варианты  Указывает список создаваемых вариантов. По умолчанию задан список "YN".

   /N                 Скрывает список вариантов в приглашении ввода. Отобразится сообщение перед приглашением, и варианты выбора остаются разрешенными.

   /CS               Разрешает чувствительность к регистру для вариантов выбора (case-sensitive). По умолчанию не имеет значения регистр вводимых символов (case-insensitive).

   /T timeout     Количество секунд паузы перед тем, как будет сделан выбор по умолчанию. Допустимы значения от 0 до 9999. Если указан 0, то паузы нет, и активируется выбор по умолчанию.

   /D вариант    Указывается выбор по умолчанию после истечения nnnn секунд. Указанный символ варианта выбора должен быть из набора в опции /C, и также должно быть указано количество nnnn секунд с опцией /T.

   /M    text        Задает отображаемое сообщение для приглашения ввода варианта выбора. Если не указано, то команда отображает только приглашение ввода.

   /?                  Покажет этот текст подсказки по команде.

ЗАМЕЧАНИЕ:

Переменная окружения ERRORLEVEL установится в значение индекса клавиши, которая была нажата из установленных вариантов выбора (см. опцию /C варианты). Для первого варианта из перечисленных будет возвращено значение 1, для второго варианта 2, и т. д. Если пользователь нажмет клавишу, которая не перечислена в вариантах выбора опции /C, то команда выдаст предупреждающий звуковой сигнал. Если команда обнаружит ошибку, то она возвратит значение ERRORLEVEL 255. Если пользователь нажмет CTRL+BREAK или CTRL+C, то команда вернет значение ERRORLEVEL 0. Когда вы используете проверку значений ERRORLEVEL в bat-скрипте, выполняйте проверки в обратном порядке значений:

if errorlevel 4 goto exit
if errorlevel 3 goto метка3
if errorlevel 2 goto метка2
if errorlevel 1 goto метка1

ПРИМЕРЫ:

   CHOICE /?
   CHOICE /C YNC /M "Нажмите Y для Yes, N для No или C для Cancel."
   CHOICE /T 10 /C ync /CS /D y
   CHOICE /C ab /M "Выберите a для варианта 1 и b для варианта 2."
   CHOICE /C ab /N /M "Выберите a для варианта 1 и b для варианта 2."

Как аналогичное действие делается на Linux, см. [3].

[Ссылки]

1. MS-DOS Batch file pause with enter key site:stackoverflow.com.
2. Detecting key presses in DOS batch files site:computerhope.com.
3. Как заставить скрипт Ubuntu ждать нажатия клавиши.