script - ¿Cómo puedo hacer un aviso "¿está seguro" en un archivo por lotes de Windows?
start cmd (7)
Aquí hay un ejemplo simple que uso en una secuencia de comandos de copia de seguridad (.bat / batch) en Windows 10, lo 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!
...
Puedes tener tantos como necesites de estos bloques.
Tengo un archivo por lotes que automatiza la copia de un grupo de archivos de un lugar a otro y de nuevo para mí. Lo único es tanto como lo que me ayuda. Sigo seleccionando accidentalmente ese comando fuera de mi búfer de comando y sobrescribiendo en masa los cambios sin compromiso.
¿Qué código necesitaría para mi archivo .bat para que dijera "¿estás seguro?", Y ¿me harías escribir "y" antes de ejecutar el resto del archivo? Si se escribe algo que no sea "y", debe salir de la ejecución en esa línea.
Edición del 27 de noviembre Ok, marqué esto sin respuesta nuevamente porque todavía no lo puedo descifrar. Cuando llamo "salir"; cierra cmd.exe que no es lo que quiero. Todo esto porque Windows implementó el búfer de comandos incorrectamente [de manera diferente a lo que estoy acostumbrado al menos]
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%== Y goto ...
if %errorlevel%== N exit
El comando de choice
no está disponible en todas partes. Con las versiones más nuevas de Windows, el comando set
tiene la opción /p
, puede obtener la entrada del usuario
SET /P variable=[promptString]
ver set /?
para más información
Hay dos comandos disponibles para las solicitudes del usuario en la línea de comandos de Windows:
- set con opción
/P
disponible en todas las versiones de Windows NT con extensiones de comando habilitadas 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 de servidor posteriores de Windows.
set es un comando interno del procesador de comandos de Windows cmd.exe
. La opción /P
para solicitar 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 más en la actualidad.
here es una aplicación de consola separada (comando externo) ubicada en %SystemRoot%/System32
. choice.exe
de Windows Server 2003 se puede copiar en el directorio %SystemRoot%/System32
en una máquina con Windows XP para usar en Windows XP, como muchos otros comandos no disponibles de manera predeterminada en Windows XP, pero están 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:
- CHOICE solo acepta claves (respectivamente caracteres leídos desde STDIN ) especificados después de la opción
/C
(y Ctrl + C ) y emite un pitido de error si el usuario presiona una tecla incorrecta. - 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 finalice la entrada con RETURN o ENTER .
- Con CHOICE es posible 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.
- El resultado es mejor al responder el aviso de forma automática desde otro archivo por lotes que llama al archivo por lotes con el mensaje usando algo como
echo Y | call PromptExample.bat
echo Y | call PromptExample.bat
al usar CHOICE . - La evaluación de la elección del usuario es mucho más fácil con CHOICE debido a las salidas de CHOICE con un valor según la tecla presionada (carácter) que se asigna a ERRORLEVEL que se puede evaluar fácilmente a continuación.
- La variable de entorno utilizada en SET / P no se define si el usuario pulsa solo la tecla RETORNO o ENTRAR y no se definió antes de avisar al usuario. La variable de entorno utilizada en la línea de comando SET / P conserva su valor actual si se definió anteriormente y el usuario presiona simplemente RETURN o ENTER .
- El usuario tiene la libertad de ingresar cualquier cosa al recibir un SET / P incluyendo una cadena que resulta más tarde en una ejecución de ejecución del archivo por lotes por
cmd
debido a un error de sintaxis, o en la ejecución de comandos no incluidos en el archivo por lotes en no es un buen archivo por lotes codificado. Se necesitan algunos esfuerzos para proteger SET / P contra por error o por una entrada del usuario intencionalmente incorrecta.
Aquí hay un ejemplo rápido con CHOICE preferido y, alternativamente, SET / P on choice.exe
no disponible en la computadora usada 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 de proceso por lotes utiliza extensiones de comando que no están disponibles en Windows 95/98 / ME utilizando command.com
lugar de cmd.exe
como intérprete de comandos.
La línea de comando set "UserChoice=!UserChoice: =!"
se agrega para que sea posible llamar a este archivo por lotes con echo Y | call PromptExample.bat
echo Y | call PromptExample.bat
en Windows NT4 / 2000 / XP y no requiera el uso de echo Y| call PromptExample.bat
echo Y| call PromptExample.bat
. Elimina todos los espacios de la lectura de cadenas de STDIN antes de ejecutar las dos comparaciones de cadenas.
echo Y | call PromptExample.bat
echo Y | call PromptExample.bat
provoca que Y SPACE se asigne a la variable de entorno UserChoice
. Eso resultaría en el procesamiento del aviso dos veces debido a que "Y "
no distingue entre mayúsculas y minúsculas con "N"
o "Y"
sin eliminar primero todos los espacios. Así que UserChoice
con Y SPACE como valor daría como resultado ejecutar el aviso una segunda vez con la opción N
definida como predeterminada en el archivo de proceso por lotes en la segunda ejecución de aviso, lo que da como resultado una salida inesperada del procesamiento de archivo por lotes. Sí, el uso seguro de SET / P es realmente complicado, ¿no?
Para obtener más detalles sobre el uso de SET / P y CHOICE para solicitar al usuario una opción de una lista de opciones, consulte respuesta en Cómo detener el intérprete de comandos de Windows para que no ejecute el archivo por lotes en una entrada de usuario incorrecta.
Algunos consejos más:
- SI compara las dos cadenas a la izquierda y derecha del operador de comparación con las comillas dobles incluidas . Por lo tanto, la comparación entre mayúsculas y minúsculas no es el valor de
UserChoice
conN
eY
, sino el valor deUserChoice
rodeado por"
con"N"
e"Y"
. - Los operadores de comparación IF
EQU
yNEQ
están diseñados para comparar dos enteros en el rango -2147483648 a 2147483647 y no para comparar dos cadenas.EQU
yNEQ
también funcionan para comparaciones de cadenas, pero resultan en la comparación de cadenas en comillas dobles en un intento inútil de convertir la cadena izquierda en un entero.EQU
yNEQ
pueden usarse solo con extensiones de comando habilitadas. Los operadores de comparación para las comparaciones de cadenas son==
ynot ... ==
que funcionan incluso con extensiones de comandos deshabilitadas, ya que inclusocommand.com
de MS-DOS y Windows 95/98 / ME ya los admiten. Para obtener más información sobre los operadores de comparación IF , vea el símbolo equivalente a NEQ, LSS, GTR, etc. en los archivos por lotes de Windows . - El comando
goto :EOF
requiere extensiones de comando habilitadas para salir realmente del procesamiento de archivos por lotes. Para más detalles, ver ¿A dónde regresa 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 con atención todas las páginas de ayuda que se muestran para cada comando.
-
choice /?
-
echo /?
-
endlocal /?
-
goto /?
-
if /?
-
set /?
-
setlocal /?
Ver también:
- Esta respuesta proporciona detalles sobre los comandos SETLOCAL y ENDLOCAL .
- ¿Por qué no hay salida de cadena con ''echo% var%'' después de usar ''set var = text'' en la línea de comandos?
Explica la razón por la que se usa elset "variable=value"
sintaxisset "variable=value"
al asignar una cadena a una variable de entorno. - Una sola línea con múltiples comandos usando el archivo de proceso por lotes de Windows para obtener detalles sobre
if errorlevel X
comportamiento deif errorlevel X
y el operador&
. - Documentación de Microsoft para el uso de operadores de redirección de comandos que explican el operador de redirección
|
y manejar STDIN . - Artículo de Wikipedia sobre las variables de entorno de Windows para obtener una explicación de
SystemRoot
. - DosTips tema del foro ECHO. NO DA el texto o la línea en blanco - En lugar de eso use ECHO /
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
Si desea que el programa por lotes salga nuevamente al mensaje y no cierre el mensaje (AKA 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...
pruebe el comando CHOICE , por ejemplo
CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."