if-statement - por - if en batch
¿Puedo tener un bloque IF en el archivo por lotes de DOS? (5)
De hecho, puede colocar crear un bloque de instrucciones para ejecutar después de un condicional. Pero tienes la sintaxis equivocada. Los paréntesis se deben usar exactamente como se muestra:
if <statement> (
do something
) else (
do something else
)
Sin embargo, no creo que haya ninguna sintaxis incorporada para else-if
sentencias else-if
. Desgraciadamente, necesitará crear bloques anidados de sentencias if
para manejar eso.
En segundo lugar, esa %GPMANAGER_FOUND% == true
parece sospechosa. No sé en qué se configura la variable de entorno ni cómo la configura, pero dudo mucho que el código que ha mostrado produzca el resultado que está buscando.
El siguiente código de muestra funciona bien para mí:
@echo off
if ERRORLEVEL == 0 (
echo GP Manager is up
goto Continue7
)
echo GP Manager is down
:Continue7
Tenga en cuenta algunos detalles específicos sobre mi código de muestra:
- El espacio agregado entre el final del enunciado condicional y el paréntesis de apertura.
- Estoy
@echo off
para evitar ver todas las declaraciones impresas en la consola mientras se ejecutan, y en su lugar solo veo el resultado de aquellas que específicamente comienzan conecho
. - Estoy usando la variable
ERRORLEVEL
incorporada solo como prueba. Lea más here
En un archivo por lotes de DOS, solo podemos tener 1 línea si el cuerpo de la declaración es? Creo que encontré un lugar que podría usar ()
para un bloque if igual al {}
usado en lenguajes de programación similares a C, pero no está ejecutando las declaraciones cuando intento esto. Sin mensaje de error tampoco. Este es mi código:
if %GPMANAGER_FOUND%==true(echo GP Manager is up
goto Continue7
)
echo GP Manager is down
:Continue7
Extrañamente, ni "GP Manager está activo" ni "GP Manager está inactivo" se imprime cuando ejecuto el archivo por lotes.
En lugar de este desorden, intente usar el signo & y el doble ampersand && (condicional a errorlevel 0) como separadores de comando.
Arreglé un fragmento de script con este truco, para resumir, tengo tres archivos de proceso por lotes, uno que llama a los otros dos después de haber encontrado qué letras se han asignado las unidades de respaldo externas. Dejo el primer archivo en la unidad externa principal para que las llamadas a su rutina de copia de seguridad funcionen bien, pero las llamadas a la segunda requieren un cambio de unidad activo. El siguiente código muestra cómo lo arreglé:
para %% b en (defghijklmnopqrstuvwx yz) DO (si existe "%% b: / Backup.cmd" %% b: & CALL "%% b: / Backup.cmd")
Lógicamente, la respuesta de Cody debería funcionar. Sin embargo, no creo que el símbolo del sistema maneje un bloque de código lógicamente. Por mi vida, no puedo lograr que funcione correctamente con más de un comando dentro del bloque. En mi caso, pruebas exhaustivas revelaron que todos los comandos dentro del bloque se almacenan en caché y se ejecutan simultáneamente al final del bloque. Esto, por supuesto, no produce los resultados esperados. Aquí hay un ejemplo simplificado:
if %ERRORLEVEL%==0 (
set var1=blue
set var2=cheese
set var3=%var1%_%var2%
)
Esto debería proporcionar var3 con el siguiente valor:
blue_cheese
sino que cede:
_
porque los 3 comandos se almacenan en caché y se ejecutan simultáneamente al salir del bloque de código.
Pude superar este problema volviendo a escribir el bloque if para ejecutar solo un comando - goto - y agregar algunas etiquetas. Es torpe, y no me gusta mucho, pero al menos funciona.
if %ERRORLEVEL%==0 goto :error0
goto :endif
:error0
set var1=blue
set var2=cheese
set var3=%var1%_%var2%
:endif
Me encontré con este artículo en los resultados devueltos por una búsqueda relacionada con el comando IF en un archivo por lotes, y no pude resistir la oportunidad de corregir la idea errónea de que los bloques IF están limitados a comandos individuales. A continuación se muestra una parte de un script de comandos de Windows NT de producción que se ejecuta a diario en la máquina en la que estoy redactando esta respuesta.
if "%COPYTOOL%" equ "R" (
WWLOGGER.exe "%APPDATA%/WizardWrx/%~n0.LOG" "Using RoboCopy to make a backup of %USERPROFILE%/My Documents/Outlook Files/*"
%TOOLPATH% %SRCEPATH% %DESTPATH% /copyall %RCLOGSTR% /m /np /r:0 /tee
C:/BIN/ExitCodeMapper.exe C:/BIN/ExitCodeMapper.INI[Robocopy] %TEMP%/%~n0.TMP %ERRORLEVEL%
) else (
WWLOGGER.exe "%APPDATA%/WizardWrx/%~n0.LOG" "Using XCopy to make a backup of %USERPROFILE%/My Documents/Outlook Files/*"
call %TOOLPATH% "%USERPROFILE%/My Documents/Outlook Files/*" "%USERPROFILE%/My Documents/Outlook Files/_backups" /f /m /v /y
C:/BIN/ExitCodeMapper.exe C:/BIN/ExitCodeMapper.INI[Xcopy] %TEMP%/%~n0.TMP %ERRORLEVEL%
)
Quizás los bloques de dos o más líneas se aplican exclusivamente a los scripts de comando de Windows NT (archivos .CMD), porque una búsqueda en el directorio de scripts de producción de una aplicación que está restringida a archivos por lotes antiguos (.BAT) reveló solo bloques de un comando . Dado que la aplicación se ha destinado al mantenimiento extendido (lo que significa que no participo activamente en su apoyo), no puedo decir si eso se debe a que no necesitaba más de una línea o si no podía hacer que funcionara.
De todos modos, si esto último es cierto, hay una solución simple; mueva las líneas múltiples a un archivo por lotes separado o a una subrutina de archivo por lotes. Sé que este último funciona en ambos tipos de scripts.
Tal vez un poco tarde, pero espero que sea genial:
@echo off
if %ERRORLEVEL% == 0 (
msg * 1st line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue1
)
:Continue1
If exist "C:/Python31" (
msg * 2nd line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue2
)
:Continue2
If exist "C:/Python31/Lib/site-packages/PyQt4" (
msg * 3th line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue3
)
:Continue3
msg * 4th line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue4
)
:Continue4
msg * "Tutto a posto" rem You can relpace msg * with any othe operation...
pause