Как я могу сделать запрос «вы уверены» в пакетном файле Windows?


95

У меня есть командный файл, который автоматизирует для меня копирование группы файлов из одного места в другое и обратно. Единственное, насколько это мне помогает, я продолжаю случайно выбирать эту команду из своего буфера команд и массово перезаписывать незавершенные изменения.

Какой код мне понадобится для моего .bat-файла, чтобы он говорил «вы уверены?» И заставлял вводить «y», прежде чем он запустил остальную часть файла? Если набрано что-либо, кроме "y", выполнение должно завершиться на этой строке.

Изменить 27 ноября. Хорошо, я снова пометил это как неотвеченное, потому что до сих пор не могу понять. Когда я призываю «выйти»; он закрывает cmd.exe, чего я не хочу. Все это потому, что Windows неправильно реализовала буфер команд [по крайней мере, не так, как я привык]

Ответы:


170

Вы хотите что-то вроде:

@echo off
setlocal
:PROMPT
SET /P AREYOUSURE=Are you sure (Y/[N])?
IF /I "%AREYOUSURE%" NEQ "Y" GOTO END

echo ... rest of file ...


:END
endlocal

5
Единственное, что я хотел бы добавить, - это добавить SET AREYOUSURE=Nперед подсказкой, чтобы очистить выбор, если вы уже запускали сценарий ранее в этом командном окне. Без него по умолчанию останется выбранный ранее выбор.
isapir

4
@Igal Я уверен , что setlocalи endlocalдолжен позаботиться об этом. %AREYOUSURE%больше не будет существовать после endlocal.

1
@dudeprgm, наверное, ты прав. Думаю, я пропустил их в своем коде.
isapir

2
... было бы более ценно с некоторыми пояснительными словами о важных двух строках .
Wolf

@Joe Может быть, он не может, потому что (как и я) он (пока) не понимает их. Так что, если вы это сделаете, было бы замечательно, если бы вы могли расширить свой ответ или дать ссылку на ресурсы, объясняющие его :)
Маркус Мангельсдорф

34

попробуйте команду CHOICE , например

CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."

8
<выпендриваться> Хотя это относительно недавно. Он был добавлен в MS-DOS 6 в 1993 или 1994 годах, поэтому он может работать не со всеми реализациями </ show off>
Натан Феллман,

7
пример того, как на самом деле использовать выбор здесь computerhope.com/issues/ch001674.htm
Мэтью Лок

Он отлично работает на Windows 10 cmd.
Браулио Дж. Солано,

16

choiceКоманда не доступна везде. В более новых версиях Windows у setкоманды есть /pвозможность получить ввод пользователя

SET /P variable=[promptString]

см. set /?для получения дополнительной информации


... гораздо более проницательный, чем принятый, но мы явно живем в неотложное время.
Wolf

12

Для подсказок пользователя в командной строке Windows доступны две команды:

  • установлен с опцией, /Pдоступной во всех версиях Windows NT с включенными расширениями команд и
  • choice.exe доступен по умолчанию в Windows Vista и более поздних версиях Windows для пользователей ПК, а также в Windows Server 2003 и более поздних серверных версиях Windows.

set - это внутренняя команда командного процессора Windows cmd.exe. Возможность /Pзапрашивать у пользователя строку доступна только при включенных расширениях команд, которые включены по умолчанию, поскольку в противном случае в настоящее время почти ни один пакетный файл не будет работать.

choice.exe - это отдельное консольное приложение (внешняя команда), расположенное в %SystemRoot%\System32. choice.exeWindows Server 2003 можно скопировать в каталог %SystemRoot%\System32на компьютере с Windows XP для использования в Windows XP, как и многие другие команды, недоступные по умолчанию в Windows XP, но доступные по умолчанию в Windows Server 2003.

Лучше всего использовать CHOICE вместо SET / P по следующим причинам:

  1. CHOICE принимает только ключи (соответственно символы, считанные из STDIN ), указанные после опции /CCtrl+C), и выдает звуковой сигнал ошибки, если пользователь нажимает неправильную клавишу.
  2. ВЫБОР не требует нажатия любой другой клавиши, кроме одной из допустимых. CHOICE закрывается сразу после нажатия приемлемой клавиши, в то время как SET / P требует, чтобы пользователь завершил ввод с помощью RETURNили ENTER.
  3. С помощью CHOICE можно определить параметр по умолчанию и тайм-аут для автоматического перехода к параметру по умолчанию через несколько секунд без ожидания пользователя.
  4. Вывод лучше при автоматическом ответе на приглашение из другого пакетного файла, который вызывает пакетный файл с приглашением, используя что-то вроде echo Y | call PromptExample.batиспользования CHOICE .
  5. Оценка выбора пользователя намного проще с помощью CHOICE, потому что CHOICE выходит со значением в соответствии с нажатой клавишей (символом), которому присваивается ERRORLEVEL, который может быть легко оценен следующим.
  6. Переменная среды, используемая в SET / P , не определяется, если пользователь нажимает только клавишу RETURNили ENTERи она не была определена до запроса пользователя. Используемая переменная среды в командной строке SET / P сохраняет свое текущее значение, если оно определено ранее, и пользователь нажимает только RETURNили ENTER.
  7. Пользователь имеет право вводить что угодно при появлении запроса с помощью SET / P, включая строку, которая позже приводит к завершению выполнения командного файла cmdиз-за синтаксической ошибки или к выполнению команд, не включенных вообще в командный файл, на не хорошо закодированный командный файл. Требуются некоторые усилия, чтобы защитить SET / P от ошибочного или намеренно неправильного ввода пользователя.

Вот пример подсказки с использованием предпочтительного выбора CHOICE и альтернативы SET / P на choice.exeнедоступном на используемом компьютере под управлением Windows.

@echo off
echo This is an example for prompting a user.
echo/
if exist "%SystemRoot%\System32\choice.exe" goto UseChoice

setlocal EnableExtensions EnableDelayedExpansion
:UseSetPrompt
set "UserChoice=N"
set /P "UserChoice=Are you sure [Y/N]? "
set "UserChoice=!UserChoice: =!"
if /I "!UserChoice!" == "N" endlocal & goto :EOF
if /I not "!UserChoice!" == "Y" goto UseSetPrompt
endlocal
goto Continue

:UseChoice
%SystemRoot%\System32\choice.exe /C YN /N /M "Are you sure [Y/N]? "
if errorlevel 2 goto :EOF

:Continue
echo So your are sure. Okay, let's go ...

Примечание. В этом пакетном файле используются расширения команд, которые недоступны в Windows 95/98 / ME, которые используются command.comвместо cmd.exeинтерпретатора команд.

Командная строка set "UserChoice=!UserChoice: =!"добавлена ​​для того, чтобы можно было вызывать этот командный файл echo Y | call PromptExample.batв Windows NT4 / 2000 / XP и не требовать использования echo Y| call PromptExample.bat. Он удаляет все пробелы из строки, считанной из STDIN, перед запуском двух сравнений строк.

echo Y | call PromptExample.batприводит к тому, что YSPACE присваивается переменной среды UserChoice. Это приведет к обработке запроса дважды, поскольку "Y "регистр не равен "N"ни "Y"без удаления всех пробелов. Таким образом , UserChoiceс YSPACE в качестве значения приведет запуск быстрое второй раз с параметром , Nкак определено по умолчанию в пакетном файле на второй оперативное выполнение которых следующая приводит к неожиданному выходу из пакетной обработки файлов. Да, безопасное использование SET / P действительно сложно, не так ли?

Дополнительные сведения об использовании SET / P и CHOICE для запроса пользователю выбора из списка параметров см. В ответе на вопрос, как остановить интерпретатор команд Windows от выхода из выполнения командного файла при неправильном вводе пользователя?

Еще несколько подсказок:

  1. IF сравнивает две строки слева и справа от оператора сравнения с включением двойных кавычек. Таким образом, сравнение без учета регистра - это не значение UserChoicewith Nи Y, а значение, UserChoiceокруженное "with "N"и "Y".
  2. Операторы сравнения IFEQU и NEQпредназначены в первую очередь для сравнения двух целых чисел в диапазоне от -2147483648 до 2147483647, а не для сравнения двух строк. EQUи NEQработают также для сравнения строк, но приводят к сравнению строк в двойных кавычках при бесполезной попытке преобразовать левую строку в целое число. EQUи NEQможет использоваться только с включенными расширениями команд. Операторы сравнения для сравнения строк - это ==и, not ... ==которые работают даже с отключенными расширениями команд, поскольку даже command.comMS-DOS и Windows 95/98 / ME уже поддерживали их. Дополнительные сведения об операторах сравнения IF см. В разделе « Символ, эквивалентный NEQ, LSS, GTR и т. Д. В пакетных файлах Windows» .
  3. Команда goto :EOFтребует наличия включенных расширений команд, чтобы действительно завершить обработку пакетного файла. Подробнее см. Куда возвращается GOTO: EOF?

Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • choice /?
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?

Смотрите также:


2
Это невероятный ответ. С этого момента я использую только Choice.exe.
Bas

1
choice.exe также присутствовал в DOS с 6.0
Брайан Минтон,

1
@BrianMinton Это неверно. 16-битное приложение было доступно CHOICE.COMпо умолчанию в MS-DOS 6.0, MS-DOS 7.0, Windows 95 и Windows 98. Но оно не было choice.exeустановлено по умолчанию в Windows NT4, Windows 2000 и Windows XP. CHOICE.COMможет использоваться также в NT4, Windows 2000 и Windows XP, но было бы лучше использовать 32-битную версию choice.exeиз соответствующего набора ресурсов. См. Страницу Роба ван дер Вуда о CHOICE . Варианты частично различаются между CHOICE.COMи choice.exe. Однако вопрос не в DOS.
Mofi

5

Здесь немного проще:

@echo off
set /p var=Are You Sure?[Y/N]: 
if %var%== Y goto ...
if not %var%== Y exit

или

@echo off
echo Are You Sure?[Y/N]
choice /c YN
if %errorlevel%==1 goto yes
if %errorlevel%==2 goto no
:yes
echo yes
goto :EOF
:no
echo no

после Y введите команду, которую вы хотите выполнить. Вот для чего ... :)
Боб Смит

Я имел в виду: %errorlevel%всегда целочисленное значение. Смотрите здесь документацию, включая пример.
Стефан

1

Вот мой метод ответа да / нет .

Он также нечувствителен к регистру.

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

@echo off
choice /M "[Opt 1]  Do you want to continue [Yes/No]"
if errorlevel 255 (
  echo Error
  ) else if errorlevel 2 (
  set "YourChoice=will not"
  ) else if errorlevel 1 (
  set "YourChoice=will"
  ) else if errorlevel 0 (
  goto :EOF
  )
  echo %YourChoice%
  pause

0

Если вы хотите, чтобы пакетная программа вернулась в командную строку и не закрывала ее (AKA cmd.exe), вы можете использовать команду «exit / b».

Это может помочь.

set /p _sure="Are you sure?"
::The underscore is used to ensure that "sure" is not an enviroment
::varible
if /I NOT "_sure"=="y" (
::the /I makes it so you can
exit /b
) else (
::Any other modifications...
)

Или, если вы не хотите использовать столько строк ...

Set /p _sure="Are you sure?"
if /I NOT "_sure"=="y" exit /b
::Any other modifications and commands.

Надеюсь это поможет...


0

Вот простой пример, который я использую в сценарии резервного копирования (.bat / batch) в Windows 10, что позволяет мне использовать различные параметры при создании резервных копий.

...

:choice
set /P c=Do you want to rsync the archives to someHost[Y/N]?
if /I "%c%" EQU "Y" goto :syncthefiles
if /I "%c%" EQU "N" goto :doonotsyncthefiles
goto :choice

:syncthefiles
echo rsync files to somewhere ...
bash -c "rsync -vaz /mnt/d/Archive/Backup/ user@host:/home/user/Backup/blabla/"
echo done

:doonotsyncthefiles
echo Backup Complete!

...

Вы можете иметь столько блоков, сколько вам нужно.


0

Сначала откройте терминал.

Затем введите

cd ~
touch .sure
chmod 700 .sure

Затем откройте .sure и вставьте его внутрь.

#!/bin/bash --init-file
PS1='> '
alias y='
    $1
    exit
'
alias n='Taskkill /IM %Terminal% /f'
echo ''
echo 'Are you sure? Answer y or n.'
echo ''

После этого закройте файл.

~/.sure ; ENTER COMMAND HERE

Перед тем, как продолжить выполнение команды, вам будет предложено указать, уверены ли вы.


Может быть, в bash, но точно не в пакетном режиме.
Стефан

Ой. Думаю, нет. Он работает только для команд терминала, а не для пакетных команд. Извините за ложную информацию.
user13636521

0

Вы можете рассмотреть возможность использования подтверждения пользовательского интерфейса.

С yesnopopup.bat

@echo off

for /f "tokens=* delims=" %%# in ('yesnopopup.bat') do (
    set "result=%%#"
)

if /i result==no (
    echo user rejected the script
    exit /b 1
) 

echo continue

rem --- other commands --

пользователь увидит следующее, и в зависимости от выбора сценарий продолжит работу:

введите описание изображения здесь

с абсолютно тем же сценарием вы можете также использовать iexpYNbutton.bat, который будет создавать аналогичные всплывающие окна.

С помощью buttons.bat вы можете попробовать следующий скрипт:

@echo off

for /f "tokens=* delims=" %%# in ('buttons.bat "Yep!" "Nope!" ') do (
    set "result=%%#"
)

if /i result==2 (
    echo user rejected the script
    exit /b 1
) 

echo continue

rem --- other commands --

и пользователь увидит:

введите описание изображения здесь


-2

Открыть терминал. Введите следующее

echo>sure.sh
chmod 700 sure.sh

Вставьте это в sure.sh

#!\bin\bash

echo -n 'Are you sure? [Y/n] '
read yn

if [ "$yn" = "n" ]; then
    exit 1
fi

exit 0

Закройте файл sure.sh и введите его в терминал.

alias sure='~/sure&&'

Теперь, если вы введете "уверен" перед вводом команды, перед продолжением команды появится запрос "уверены ли вы".

Надеюсь, это будет полезно!


Может быть, в bash, но точно не в пакетном режиме.
Стефан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.