Jak mogę wyświetlić monit „Czy na pewno” w pliku wsadowym systemu Windows?


95

Mam plik wsadowy, który automatyzuje kopiowanie wielu plików z jednego miejsca do drugiego iz powrotem dla mnie. Jedyną rzeczą jest to, że pomaga mi przypadkowo wybierając to polecenie z mojego bufora poleceń i masowo nadpisując niezatwierdzone zmiany.

Jakiego kodu będę potrzebować dla mojego pliku .bat, aby napisać „czy na pewno” i zmusić mnie do wpisania „y”, zanim uruchomi resztę pliku? Jeśli zostanie wpisane cokolwiek innego niż "y", powinno zakończyć wykonywanie w tej linii.

Edytuj 27 listopada Ok, ponownie oznaczyłem to jako bez odpowiedzi, ponieważ nadal nie mogę tego rozgryźć. Kiedy wołam „Wyjdź”; zamyka cmd.exe, którego nie chcę. Wszystko to dlatego, że Windows zaimplementował niewłaściwy bufor poleceń [inaczej niż to, do czego jestem przyzwyczajony]

Odpowiedzi:


169

Chcesz coś takiego:

@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
Jedyne, co chciałbym dodać, to dodatkowa SET AREYOUSURE=Nprzed monitem, aby wyczyścić wybór, jeśli wcześniej uruchomiłeś skrypt w tym oknie poleceń. Bez tego domyślna pozostanie poprzednio wybrana opcja.
isapir

4
@Igal Jestem prawie pewien, że setlocali endlocalpowinni się tym zająć. %AREYOUSURE%nie będzie już istnieć po endlocal.

1
@dudeprgm prawdopodobnie masz rację. Myślę, że przegapiłem te w moim kodzie.
isapir

2
... byłoby bardziej wartościowe z kilkoma objaśnieniami dotyczącymi dwóch ważnych wersów .
Wolf

@Joe Może nie może, ponieważ (tak jak ja) nie (jeszcze) ich nie rozumie. Więc jeśli to zrobisz, byłoby wspaniale, gdybyś mógł rozwinąć swoją odpowiedź lub link do zasobów wyjaśniających to :)
Marcus Mangelsdorf


16

choiceKomenda nie jest dostępna wszędzie. W nowszych wersjach systemu Windows setpolecenie ma /popcję uzyskania danych wejściowych użytkownika

SET /P variable=[promptString]

zobacz, set /?aby uzyskać więcej informacji


... dużo bardziej wnikliwe niż te akceptowane, ale oczywiście żyjemy w pilnych czasach.
Wolf

12

Istnieją dwa polecenia dla monitów użytkownika w wierszu poleceń systemu Windows:

  • zestaw z opcją /Pdostępną we wszystkich wersjach systemu Windows NT z włączonymi rozszerzeniami poleceń i
  • choice.exe jest dostępny domyślnie w systemie Windows Vista i nowszych wersjach systemu Windows dla użytkowników komputerów PC oraz w systemie Windows Server 2003 i nowszych serwerowych wersjach systemu Windows.

set to wewnętrzne polecenie procesora poleceń systemu Windows cmd.exe. Opcja/P monitowania użytkownika o ciąg jest dostępna tylko przy włączonych rozszerzeniach poleceń, które są domyślnie włączone, ponieważ w przeciwnym razie prawie żaden plik wsadowy nie działałby już w dzisiejszych czasach.

choice.exe to osobna aplikacja konsolowa (polecenie zewnętrzne) znajdująca się w %SystemRoot%\System32. choice.exesystemu Windows Server 2003 można skopiować do katalogu %SystemRoot%\System32na komputerze z systemem Windows XP w celu użycia w systemie Windows XP, podobnie jak wiele innych poleceń, które nie są domyślnie dostępne w systemie Windows XP, ale są domyślnie dostępne w systemie Windows Server 2003.

Jest najlepszą praktyką do używania rzecz WYBORU nad wykorzystaniem SET / P z powodu następujących powodów:

  1. WYBÓR akceptuje tylko klucze (odpowiednio znaki odczytane ze STDIN ) określone po opcji /C(iCtrl+C ) i generuje dźwięk błędu, jeśli użytkownik naciśnie niewłaściwy klawisz.
  2. WYBÓR nie wymaga wciskania innego klawisza niż jeden z dopuszczalnych. CHOICE wychodzi natychmiast po naciśnięciu akceptowalnego klawisza, podczas gdy SET / P wymaga, aby użytkownik zakończył wprowadzanie za pomocą RETURNlub ENTER.
  3. Z WYBOREM jest to możliwe można zdefiniować opcję domyślną i limit czasu, aby automatycznie przejść do opcji domyślnej po kilku sekundach bez czekania na użytkownika.
  4. Wyjście jest lepsze po automatycznej odpowiedzi na monit z innego pliku wsadowego, który wywołuje plik wsadowy z podpowiedzią, używając czegoś podobnego echo Y | call PromptExample.batdo użycia WYBORU .
  5. Ocena wyboru użytkownika jest znacznie łatwiejsza dzięki WYBORZE, ponieważ WYBÓR wychodzi z wartością zgodną z wciśniętym klawiszem (znakiem), który jest przypisany do ERRORLEVEL, który można łatwo ocenić jako następny.
  6. Zmienna środowiskowa używana w SET / P nie jest zdefiniowana, jeśli użytkownik naciska tylko klawisz RETURNlub ENTERi nie została zdefiniowana przed monitem użytkownika. Użyta zmienna środowiskowa w wierszu poleceń SET / P zachowuje swoją bieżącą wartość, jeśli została zdefiniowana wcześniej, a użytkownik naciśnie tylko RETURNlub ENTER.
  7. Użytkownik ma swobodę wprowadzania czegokolwiek po wyświetleniu monitu za pomocą polecenia SET / P, w tym ciągu znaków, który później powoduje zakończenie wykonywania pliku wsadowego z cmdpowodu błędu składniowego lub w przypadku wykonywania poleceń niezawartych w pliku wsadowym przy nie dobrze zakodowany plik wsadowy. Wymaga pewnych wysiłków, aby zabezpieczyć SET / P przed pomyłką lub celowym błędem wprowadzonym przez użytkownika.

Oto prosty przykład użycia preferowanego WYBORU i alternatywnie SET / P na choice.exeniedostępnym na używanym komputerze z systemem 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 ...

Uwaga: Ten plik wsadowy używa rozszerzeń poleceń, które nie są dostępne w systemie Windows 95/98 / ME, używając command.comzamiast cmd.exeinterpretatora poleceń.

set "UserChoice=!UserChoice: =!"Dodano wiersz poleceń, aby umożliwić wywołanie tego pliku wsadowego echo Y | call PromptExample.batw systemie Windows NT4 / 2000 / XP i nie wymaga użycia echo Y| call PromptExample.bat. Usuwa wszystkie spacje z ciągu odczytywanego ze STDIN przed uruchomieniem dwóch porównań ciągów.

echo Y | call PromptExample.batpowoduje przypisanie YSPACE do zmiennej środowiskowej UserChoice. Spowodowałoby to dwukrotne przetworzenie zachęty, ponieważ "Y "nie uwzględnia wielkości liter równych "N"ani "Y"bez usuwania najpierw wszystkich spacji. Więc UserChoicez YSPACE jako wartość spowoduje uruchomienie szybkiego drugi raz z opcją Nzdefiniowany jako domyślny w pliku wsadowym na drugiej szybkiej realizacji których Kolejne wyniki w niespodziewanym wyjeździe z przetwarzaniem pliku wsadowego. Tak, bezpieczne korzystanie z SET / P jest naprawdę trudne, prawda?

Aby uzyskać jeszcze więcej informacji na temat używania SET / P i CHOICE do monitowania użytkownika o wybór z listy opcji, zobacz odpowiedź na temat Jak zatrzymać interpreter poleceń systemu Windows przed zakończeniem wykonywania pliku wsadowego przy nieprawidłowym wprowadzeniu użytkownika?

Kilka dodatkowych wskazówek:

  1. JEŻELI porównuje dwa ciągi po lewej i po prawej stronie operatora porównania z uwzględnieniem podwójnych cudzysłowów. Zatem porównywanie bez rozróżniania wielkości liter nie jest wartością UserChoicez Ni Y, ale wartością UserChoiceotoczoną przez "z "N"i "Y".
  2. W IF operatory porównania EQUi NEQprzeznaczone są podstawowym do porównywania dwóch liczb całkowitych w zakresie -2147483648 do 2147483647, a nie do porównywania dwóch ciągów. EQUi NEQdziała również dla porównań ciągów, ale skutkuje porównywaniem ciągów w podwójnych cudzysłowach przy bezużytecznej próbie konwersji lewego ciągu na liczbę całkowitą. EQUi NEQmoże być używany tylko z włączonymi rozszerzeniami poleceń. Operatory porównania dla porównań ciągów są ==i not ... ==działają nawet z wyłączonymi rozszerzeniami poleceń, ponieważ nawet command.comMS-DOS i Windows 95/98 / ME już je obsługiwały. Aby uzyskać więcej informacji na temat operatorów porównania JEŻELI , zobacz Symbol równoważny NEQ, LSS, GTR itp. W plikach wsadowych systemu Windows .
  3. Polecenie goto :EOFwymaga włączonych rozszerzeń poleceń, aby naprawdę zakończyć przetwarzanie plików wsadowych. Aby uzyskać więcej informacji, zobacz Gdzie powraca GOTO: EOF?

Aby zrozumieć używane polecenia i sposób ich działania, otwórz okno wiersza polecenia, wykonaj w nim następujące polecenia i przeczytaj dokładnie wszystkie strony pomocy wyświetlane dla każdego polecenia.

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

Zobacz też:


2
To niesamowita odpowiedź. Od teraz używam tylko Choice.exe.
Bas

1
choice.exe był również dostępny w DOS od 6.0
Brian Minton

1
@BrianMinton To nie jest w porządku. Aplikacja 16-bitowa CHOICE.COMbyła domyślnie dostępna w systemach MS-DOS 6.0, MS-DOS 7.0, Windows 95 i Windows 98. Ale choice.exedomyślnie nie była instalowana w systemach Windows NT4, Windows 2000 i Windows XP. CHOICE.COMmoże być używany również na NT4, Windows 2000 i Windows XP, ale lepiej byłoby użyć wersji 32-bitowej choice.exez odpowiedniego zestawu zasobów. Zobacz stronę Roba van der Woude o WYBORZE . Opcje są częściowo różne między CHOICE.COMi choice.exe. Jednak pytanie nie dotyczy DOS.
Mofi

5

Tutaj trochę łatwiej:

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

lub

@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

po Y umieść polecenie, które chcesz, aby się wydarzyło. Po to są ... :)
Bob Smith

Miałem na myśli: %errorlevel%jest zawsze wartością całkowitą. Zobacz tutaj dokumentację zawierającą przykład.
Stephan

1

Oto moja metoda odpowiedzi na tak / nie .

Nie ma też rozróżniania wielkości liter.

To po prostu sprawdza błędy podane przez dane wejściowe i ustawia choicezmienną na wszystko, czego potrzebujesz, aby można ją było użyć poniżej w kodzie.

@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

Jeśli chcesz, aby program wsadowy wyszedł z powrotem do znaku zachęty i nie zamykał znaku zachęty (AKA cmd.exe), możesz użyć "exit / b".

To może pomóc.

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...
)

Lub jeśli nie chcesz używać tylu wierszy ...

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

Mam nadzieję że to pomoże...


0

Oto prosty przykład, którego używam w skrypcie kopii zapasowej (.bat / batch) w systemie Windows 10, co pozwala mi mieć różne opcje podczas tworzenia kopii zapasowych.

...

: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!

...

Możesz mieć tyle bloków, ile potrzebujesz.


0

Najpierw otwórz terminal.

Następnie wpisz

cd ~
touch .sure
chmod 700 .sure

Następnie otwórz. Pewnie i wklej to do środka.

#!/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 ''

Następnie zamknij plik.

~/.sure ; ENTER COMMAND HERE

Spowoduje to wyświetlenie pytania, czy na pewno przed kontynuowaniem polecenia.


Może w bash, ale na pewno nie partiami.
Stephan

O. Nie sądzę. Działa tylko dla poleceń terminala, a nie poleceń wsadowych. Przepraszamy za fałszywe informacje.
user13636521

-2

Otwórz terminal. Wpisz co następuje

echo>sure.sh
chmod 700 sure.sh

Wklej to wewnątrz sure.sh

#!\bin\bash

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

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

exit 0

Zamknij sure.sh i wpisz to w terminalu.

alias sure='~/sure&&'

Teraz, jeśli wpiszesz sure przed wpisaniem polecenia, przed kontynuowaniem polecenia wyświetli się pytanie, czy jesteś pewien.

Mam nadzieję, że to jest pomocne!


Może w bash, ale na pewno nie partiami.
Stephan

Czy w ogóle przeczytałeś pytanie?
Abhishek
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.