¿Cómo puedo hacer un mensaje de "estás seguro" en un archivo por lotes de Windows?

94

Tengo un archivo por lotes que automatiza la copia de un montón de archivos de un lugar a otro y viceversa. Lo único es que, en la medida en que me ayuda, sigo seleccionando accidentalmente ese comando de mi búfer de comandos y sobrescribiendo en masa los cambios no comprometidos.

¿Qué código necesitaría para mi archivo .bat para que diga "estás seguro" y me haga escribir "y" antes de ejecutar el resto del archivo? Si se escribe algo excepto "y", debería salir de la ejecución en esa línea.

Editar 27 de noviembre Ok, marqué esto sin respuesta de nuevo porque todavía no puedo resolverlo. Cuando llamo "salir"; Cierra cmd.exe que no es lo que quiero. Todo esto porque Windows implementó el búfer de comando de manera incorrecta [de manera diferente a lo que estoy acostumbrado al menos]

Josh Ribakoff
fuente

Respuestas:

168

Quieres algo como:

@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
Joe
fuente
5
Lo único que agregaría es un adicional SET AREYOUSURE=Nantes del indicador para borrar la opción si ya ejecutó el script antes en esa ventana de comando. Sin él, el valor predeterminado seguirá siendo la opción seleccionada anteriormente.
isapir
4
@Igal Estoy bastante seguro de que el setlocaly el endlocaldeberían encargarse de eso. %AREYOUSURE%ya no existirá después del endlocal.
1
@dudeprgm probablemente tengas razón. Creo que los extrañé en mi código.
isapir
2
... sería más valioso con algunas palabras explicativas sobre las dos líneas importantes .
Wolf
@Joe Quizás no pueda porque (como yo) no los entiende (todavía). Entonces, si lo hace, sería increíble si pudiera ampliar su respuesta o vincular a los recursos que lo explican :)
Marcus Mangelsdorf
33

prueba el comando CHOICE , por ejemplo

CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."
Steven A. Lowe
fuente
8
<presumir> Aunque esto es relativamente nuevo. Se agregó en MS-DOS 6 en 1993 o 1994, por lo que puede que no funcione con todas las implementaciones </ show off>
Nathan Fellman
7
ejemplo de cómo utilizar la opción en realidad aquí computerhope.com/issues/ch001674.htm
Matthew Lock
15

El choicecomando no está disponible en todas partes. Con las versiones más recientes de Windows, el setcomando tiene la /popción de obtener la entrada del usuario

SET /P variable=[promptString]

ver set /?para más información

ghostdog74
fuente
... mucho más perspicaz que la aceptada, pero obviamente vivimos en tiempos urgentes.
Wolf
10

Hay dos comandos disponibles para las indicaciones del usuario en la línea de comandos de Windows:

  • establecer con la opción /Pdisponible en todas las versiones de Windows NT con extensiones de comando habilitados y
  • choice.exe disponible de forma predeterminada en Windows Vista y versiones posteriores de Windows para usuarios de PC y en Windows Server 2003 y versiones posteriores de servidor de Windows.

set es un comando interno del procesador de comandos de Windows cmd.exe. La opción /Pde pedirle a un usuario una cadena está disponible solo con las extensiones de comando habilitadas que están habilitadas de manera predeterminada, ya que de lo contrario casi ningún archivo por lotes funcionaría hoy en día.

choice.exe es una aplicación de consola separada (comando externo) ubicada en %SystemRoot%\System32. choice.exede Windows Server 2003 se puede copiar en el directorio %SystemRoot%\System32de una máquina con Windows XP para su uso en Windows XP, como muchos otros comandos no disponibles de forma predeterminada en Windows XP, pero disponibles de forma predeterminada en Windows Server 2003.

Es una buena práctica favorecer el uso de CHOICE sobre el uso de SET / P debido a las siguientes razones:

  1. CHOICE acepta solo las teclas (respectivamente caracteres leídos de STDIN ) especificadas después de la opción /C(y Ctrl+C) y emite un pitido de error si el usuario presiona una tecla incorrecta.
  2. CHOICE no requiere presionar ninguna otra tecla que no sea una de las aceptables. CHOICE sale inmediatamente una vez que se presiona una tecla aceptable, mientras que SET / P requiere que el usuario termine la entrada con RETURNo ENTER.
  3. Es posible con CHOICE definir una opción predeterminada y un tiempo de espera para continuar automáticamente con la opción predeterminada después de algunos segundos sin esperar al usuario.
  4. La salida es mejor al responder el mensaje automáticamente desde otro archivo por lotes que llama al archivo por lotes con el mensaje usando algo como echo Y | call PromptExample.batel uso de CHOICE .
  5. La evaluación de la elección del usuario es mucho más fácil con CHOICE debido a que CHOICE sale con un valor de acuerdo con la tecla presionada (carácter) que se asigna a ERRORLEVEL que se puede evaluar fácilmente a continuación.
  6. La variable de entorno utilizada en SET / P no se define si el usuario presiona solo la tecla RETURNo ENTERy no se definió antes de preguntarle al usuario. La variable de entorno utilizada en la línea de comando SET / P mantiene su valor actual si se definió antes y el usuario presiona RETURNo ENTER.
  7. El usuario tiene la libertad de ingresar cualquier cosa cuando se le solicite SET / P, incluida una cadena que resulte más tarde en una salida de la ejecución del archivo por lotes cmddebido a un error de sintaxis, o en la ejecución de comandos no incluidos en absoluto en el archivo por lotes en buen archivo por lotes codificado. Se necesitan algunos esfuerzos para conseguir que SET / P esté seguro contra un error o una entrada intencionalmente incorrecta del usuario.

A continuación, se muestra un ejemplo rápido en el que se usa OPCIÓN preferida y, alternativamente, SET / P en choice.exeno disponible en computadoras usadas con 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 ...

Nota: Este archivo por lotes utiliza extensiones de comando que no están disponibles en Windows 95/98 / ME en command.comlugar de cmd.execomo intérprete de comandos.

La línea de comando set "UserChoice=!UserChoice: =!"se agrega para que sea posible llamar a este archivo por lotes echo Y | call PromptExample.baten Windows NT4 / 2000 / XP y no requiere el uso de echo Y| call PromptExample.bat. Elimina todos los espacios de la cadena leída desde STDIN antes de ejecutar las dos comparaciones de cadenas.

echo Y | call PromptExample.batda como resultado que YSPACE se asigne a la variable de entorno UserChoice. Eso resultaría en procesar el mensaje dos veces debido a "Y "que no es igual a mayúsculas y minúsculas "N"ni "Y"sin eliminar primero todos los espacios. Entonces, UserChoicecon YSPACE como valor resultaría en ejecutar el mensaje por segunda vez con la opción Ndefinida como predeterminada en el archivo por lotes en la segunda ejecución del mensaje, lo que a continuación da como resultado una salida inesperada del procesamiento del archivo por lotes. Sí, el uso seguro de SET / P es realmente complicado, ¿no?

Para obtener aún más detalles sobre el uso de SET / P y CHOICE para solicitar al usuario una elección de una lista de opciones, consulte la respuesta sobre ¿Cómo evitar que el intérprete de comandos de Windows salga de la ejecución de archivos por lotes en una entrada de usuario incorrecta?

Algunas sugerencias más:

  1. IF compara las dos cadenas izquierda y derecha del operador de comparación con la inclusión de comillas dobles. Por lo tanto, la comparación que no distingue entre mayúsculas y minúsculas no es el valor de UserChoicecon Ny Y, sino el valor de UserChoicerodeado por "con "N"y "Y".
  2. Los operadores de comparación IFEQU y NEQestán diseñados principalmente para comparar dos enteros en el rango -2147483648 a 2147483647 y no para comparar dos cadenas. EQUy NEQfunciona también para las comparaciones de cadenas, pero resulta en comparar cadenas entre comillas dobles en un intento inútil de convertir la cadena izquierda en un entero. EQUy solo NEQse puede usar con extensiones de comando habilitadas. Los operadores de comparación para las comparaciones de cadenas son ==y not ... ==que funcionan incluso con extensiones de comando deshabilitadas, ya que incluso command.comMS-DOS y Windows 95/98 / ME ya las admitían. Para obtener más detalles sobre los operadores de comparación IF , consulte Símbolo equivalente a NEQ, LSS, GTR, etc. en archivos por lotes de Windows .
  3. El comando goto :EOFrequiere extensiones de comando habilitadas para salir realmente del procesamiento de archivos por lotes. Para obtener más detalles, consulte ¿A dónde vuelve GOTO: EOF?

Para comprender los comandos utilizados y cómo funcionan, abra una ventana de símbolo del sistema, ejecute allí los siguientes comandos y lea todas las páginas de ayuda que se muestran para cada comando con mucho cuidado.

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

Ver también:

Mofi
fuente
1
Ésta es una respuesta increíble. Solo estoy usando Choice.exe de ahora en adelante.
Bas
choice.exe también estuvo presente en DOS desde 6.0
Brian Minton
@BrianMinton Eso no está bien. La aplicación de 16 bits estaba disponible CHOICE.COMpor defecto en MS-DOS 6.0, MS-DOS 7.0, Windows 95 y Windows 98. Pero no estaba choice.exeinstalada por defecto en Windows NT4, Windows 2000 y Windows XP. CHOICE.COMtambién se podría usar en NT4, Windows 2000 y Windows XP, pero sería mejor usar 32 bits choice.exedel kit de recursos apropiado. Consulte la página de Rob van der Woude sobre CHOICE . Las opciones son en parte diferentes entre CHOICE.COMy choice.exe. Sin embargo, la pregunta no es sobre DOS.
Mofi
5

Aquí un poco más fácil:

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

o

@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
Bob Smith
fuente
después de la Y pon el comando que quieres que suceda. Para eso son los ... :)
Bob Smith
Quiero decir: %errorlevel%siempre es un valor entero. Consulte aquí la documentación que incluye un ejemplo.
Stephan
1

Este es mi método para obtener una respuesta sí / no .

También no distingue entre mayúsculas y minúsculas.

Esto solo verifica los errores dados por la entrada y establece la choicevariable en lo que necesite para que pueda usarse a continuación en el código.

@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
Ste
fuente
0

Si desea que el programa por lotes vuelva al indicador y no cierre el indicador (también conocido como cmd.exe), puede usar "exit / b".

Esto puede ayudar.

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

O si no quieres usar tantas líneas ...

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

Espero que esto ayude...

Z. Mickaels
fuente
0

Aquí hay un ejemplo simple que utilizo en un script de copia de seguridad (.bat / batch) en Windows 10, que me permite tener diferentes opciones al hacer copias de seguridad.

...

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

...

Puede tener tantos como necesite de estos bloques.


fuente
0

Primero, abre la terminal.

Luego, escriba

cd ~
touch .sure
chmod 700 .sure

A continuación, abra .sure y pegue esto dentro.

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

Después de eso, cierre el archivo.

~/.sure ; ENTER COMMAND HERE

Esto le indicará si está seguro antes de continuar con el comando.

usuario13636521
fuente
Quizás en bash, pero ciertamente no en lote.
Stephan
Oh. Supongo que no. Solo funciona para comandos de terminal, no para comandos por lotes. Perdón por la información falsa.
user13636521
-1

Terminal abierto. Escriba lo siguiente

echo>sure.sh
chmod 700 sure.sh

Pega esto dentro de sure.sh

#!\bin\bash

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

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

exit 0

Cierre sure.sh y escriba esto en la terminal.

alias sure='~/sure&&'

Ahora, si escribe sure antes de escribir el comando, le dará un mensaje de si está seguro antes de continuar con el comando.

¡Espero que esto sea útil!

Colaborador anónimo
fuente
Quizás en bash, pero ciertamente no en lote.
Stephan