Archivos por lotes (batch) Los tipos de fichero que puede ejecutar MS-DOS desde línea de comandos debentener la extensión .exe, .com o .bat. Los dos primeros son archivos en lenguaje máquina (compilados), el tercero es un fichero ASCII, cuyas líneas son comandos MS-DOS que serán interpretados por la shell. Para llamarlos basta con escribir su nombre en la línea de comandos, no es necesario especificar la extensión, pero deben estar accesibles: bien en el directorio actual ( . ), o bien en alguno de los directorios especificados en la variable PATH. ¿Qué sucede si dos archivos ejecutables se denominan igual?, los ficheros bat son los que tienen menor prioridad de ejecución: 1º) macros 2º) comandos internos 3º) .exe 4º) .com 5º) .bat Ejemplo. El siguiente archivo bat crea una unidad virtual Z: para el directorio en que nos encontramos: uvz.bat subst Z: . C:\Documents and Settings\Administrador>copy con uvz.bat subst Z: . ^Z 1 archivos copiados. C:\Documents and Settings\Administradoruebas>uvz ejecuto el archivo bat C:\Documents and Settings\Administrador>subst Z: . ejecutar C:\Documents and Settings\Administradorebas>z: Z:\>subst Z:\: => C:\Documents and Settings\Administrador Puede contener múltiples líneas: uvz.bat subst /d Z: subst Z: . subst comentarios me muestra el comando que va a En un archivo por lotes podemos incluir líneas de comentario con la palabra REM (remark): REM comentario Comando ECHO Nos permite visualizar mensajes en pantalla. ECHO [mensaje | ON | OFF] Muestra mensajes o activa y desactiva el eco del comando. Escriba ECHO sin parámetros para mostrar la configuración actual del eco. echo. inserta una línea en blanco El siguiente bat muestra un listado simple de directorio, separando archivos de directorios: REM list.bat echo --- ARCHIVOS --dir /a-d /b /on echo --- DIRECTORIOS --dir /ad /b /on Eco de los comandos Cada comando de un archivo por lotes es visualizado en pantalla antes de ser ejecutado. Esto puede estar bien para depuración, pero a veces es un poco molesto: La ejecución del fichero bat anterior (list.bat) sería: C:\Documents and Settings\Administrador>list C:\Documents and Settings\Administrador>REM list.bat <---o C:\Documents and Settings\Administrador>echo --- ARCHIVOS --- <---o --- ARCHIVOS --C:\Documents and Settings\Administrador>dir /a-d /b /on <---o ntuser.bak ntuser.dat NtUser.dat.LOG ntuser.ini C:\Documents and Settings\Administrador>echo --- DIRECTORIOS --- <---o --- DIRECTORIOS --C:\Documents and Settings\Administrador>dir /ad /b /on <---o Escritorio Favoritos Menú Inicio Mis documentos Si queremos anular este comportamiento, y que un comando se ejecute de manera silenciosa, precedemos al comando del carácter arroba: @dir /a-d /b /on Pero si deseamos anular el eco para todos los comandos, la primera línea será el comando ECHO OFF: @echo off REM list.bat echo --- ARCHIVOS --dir /a-d /b /on echo --- DIRECTORIOS --dir /ad /b /on Ahora la ejecución del fichero bat es la siguiente: C:\Documents and Settings\Administrador>list --- ARCHIVOS --ntuser.bak ntuser.dat NtUser.dat.LOG ntuser.ini --- DIRECTORIOS --Escritorio Favoritos Menú Inicio Mis documentos Estructura de bifurcación GOTO En un archivo bat la ejecución de los comandos no es necesariamente secuencial, la intrucción GOTO nos permite continuar la ejecución del archivo BAT en otro punto del mismo: GOTO etiqueta -comandos:etiqueta -comandosEl siguiente archivo zzz.bat muestra de manera indefinida los segundos pasar: @echo off set cont=0 :bucle cls echo Mira pasar el tiempo ... %cont% ping -n 1 -w 800 0.0.0.1 > NUL set /a cont=cont+1 goto bucle Para la mayoría de los comandos, cuando no pueden ejecutarse por algún motivo, se muestra el mensaje de error correspondiente y continúa la ejecución con el siguiente de la lista. En el caso del GOTO (y unos pocos más), si no existiera la etiqueta 'bucle' finalizaría el programa con un error. El siguiente programa BAT no funcionaría como se espera.. ..... . interrumpir el proceso.) le precederemos del símbolo ^ (ALT + 94). Pausar el programa A veces interesará suspender temporalmente la ejecución de un archivo bat para que el usuario lleve a cabo alguna acción: encender la impresora.Su uso principal es en las estructuras if.html . pues interpreta el pipe como "redirección a entrada estándar del comando /?": ayuda. insertar cierto disquete. operadoress de redirección. @ECHO Se van a borrar todos los archivos de la unidad Z: @ECHO Ctrl + C para interrumpir @PAUSE . Carácter de escape en MS-DOS Cuando deseamos permutar el significado de alguno de los caracteres con significado especial (pipe..... programa o archivo por lotes ejecutable. La solución sería: echo reboot [ hh:mm ^| /? ] También sería útil en un caso como el siguiente: echo ^<html^> > pagweb.. Ejemplos: @ECHO OFF CLS ECHO Inserte el diskette de nóminas en la unidad A: PAUSE .bat @echo off echo Sintaxis: echo reboot [ hh:mm | /? ] X:\>ayuda Sintaxis: "/?" no se reconoce como un comando interno o externo. PAUSE Suspende el proceso de un programa por lotes y por muestra el mensaje Presione una tecla para continuar. bat desde línea de comandos. NOTA: Funciona a partir de W2000. grosero.. que serán almacenados en las denominadas variables posicionales: %0. podemos introducir la información a través de de un pipe. y deben estar habilitadas las extensiones de comando.Paso de parámetros a un archivo bat desde línea de comandos Podemos introducir datos al fichero . .. echo nunca me gustó el nombre de %nombrex% Por recibir el argumento desde entrada estándar.bat ¿Cómo te llamas? nunca me gustó el nombre de @echo off NOTA: Podemos usar comillas en el mensaje que no serán visualizadas: set /p nombre="¿Cómo te llamas? " 2.bat ¿Cómo te llamas? Paco Pico nunca me gustó el nombre de Paco Pico X:\pruebas>echo Ferreolo Anastasio | grosero..para evitar que la shell interprete cierto símbolos mayor/menor como operadores de redireccionamiento. o redirigida desde un archivo o dispositivo: X:\pruebas>grosero. Paso de parámetros a un archivo bat Hay dos métodos para pasar información: 1) línea de comandos 2) entrada estándar 1. Muestra el mensaje antes de leer la línea de entrada. %2. %1.bat @echo off set /p nombre=¿Cómo te llamas? echo. %9 En %0 se almacena el nombre del comando En %1 se guarda el valor del primer argumento .bat ¿Cómo te llamas? nunca me gustó el nombre de Ferreolo Anastasio X:\pruebas>grosero.bat < grosero.Paso de parámetros a un archivo bat desde entrada estándar SET /P variable=[mensaje] El modificador /P permite establecer el valor de una variable para una línea de entrada escrita por el usuario. vemos que si la frase tiene más de 9 palabras.bat @echo %* Y sin mucho esfuerzo podemos dar la vuelta a una frase de hasta 9 palabras: reverse. reverse no las visualiza: X:\>reverse En un lugar de la mancha cuyo nombre no quiero acordarme nombre cuyo de Mancha la de lugar En Cuando los argumentos desde línea de comandos son más de 9.bat para ver el funcionamiento de shift: reverse. El siguiente programa repite lo que introducimos desde línea de comandos (excepto el nombre del comando): repite. y así sucesivamente. es necesario irlos desplazando si queremos leer todos.En %2 se guarda el valor del segundo argumento. El comando SHIFT desplaza el valor de todos los argumentos posicionales un lugar hacia la izquierda: modifiquemos un poco el fichero reverse. El parámetro %* contiene la lista con todos los argumentos introducidos desde línea de comandos.bat @echo %9 %8 %7 %6 %5 %4 %3 %2 %1 X:\>repite lo que yo te diga lo que yo te diga X:\>reverse lo que yo te diga diga te yo que lo SHIFT En el ejemplo anterior.bat @echo off . Las siguientes líneas provocarán un error cuando el usuario no introduzca ningún valor en la variable posicional %1: IF %1==TE goto TERUEL IF NOT EXIST %1 echo NO ENCUENTRO EL ARCHIVO pues la comparación a realizar sería: IF ==TE goto TERUEL <-. Por ejemplo: SHIFT /2 Realiza el desplazamiento a partir del argumento %2. EXIST archivo .echo %9 %8 %7 %6 %5 %4 %3 %2 %1 shift echo %9 %8 %7 %6 %5 %4 %3 %2 %1 shift echo %9 %8 %7 %6 %5 %4 %3 %2 %1 X:\> en un lugar de la mancha cuyo nombre no quiero acordarme… nombre cuyo de Mancha la de lugar un En no no nombre cuyo de Mancha la de lugar un quiero quiero no nombre cuyo de Mancha la de lugar Si las extensiones de comando están habilitadas. conviene añadir algún delimitador con el fin de evitar comparaciones con un "vacío".Niega la condición: el comando se ejecutará si la condición es falsa.ERROR de SINTAXIS !!! IF NOT EXIST echo NO ENCUENTRO EL ARCHIVO <-. dejando fijos los parámetros %0 y %1 Estructura de control: IF Mediante la estructura IF podemos realizar un procesamiento condicional en programas por lotes.La condición es verdadera si las cadenas de texto son exactamente iguales (comparación de cadenas case sensitive). Cuando no estemos muy seguros de que los operandos del IF vayan a contener algún valor. la segunda deberemos encerrarla entre comillas: IF '%1'=='TE' goto TERUEL .La condición es verdadera si la ejecución del último comando devolvió un código de salida igual o mayor (>=) que el número especificado. podemos comenzar los deplazamientos en un determinado parámetro.Es verdadero si existe el archivo especificado.ERROR de SINTAXIS !!! Para la primera existen infinitas soluciones. ERRORLEVEL número . NOT . comando .es el comando que se ejecutará si se cumple la condición. IF [NOT] {cadena1==cadena2 | EXIST archivo | ERRORLEVEL número} comando cadena1==cadena2 . bat: @echo off if "%1"=="/?" goto AYUDA if "%1"=="" goto FIN echo %* goto FIN :AYUDA echo.%1==. si no existe nos informa del fallo: @echo off if NOT EXIST "%1" goto ERROR echo %TIME% >> %1 goto FIN :ERROR echo No se encontró el fichero %1 :FIN .IF IF IF IF "%1"=="TE" goto TERUEL {%1}=={TE} goto TERUEL . echo Este comando repite la frase que usted escriba echo .Sintaxis: echo repite [ /? ^| frase] echo. la alternativa es ejecutar varias IF una a continuación de otra: if "%1"=="/?" goto AYUDA if "%1"=="--help" goto AYUDA if "%1"=="" goto AYUDA AND Para el operador AND debemos anidar IF: IF EXIST "%1" IF EXIST "%2" COMP %1 %2 EJEMPLOS En el siguiente ejemplo se ha añadido una ayuda al comando repite. :FIN El siguiente programa añade la hora actual al archivo introducido desde línea de comandos.TE goto TERUEL gamusino%1verde==gamusinoTEverde goto TERUEL IF NOT EXIST "%1" echo NO ENCUENTRO EL ARCHIVO OR No existe el operador OR. comandos cuando errorlevel>=1 :CORRECTO .comandos cuando errorlevel>=1 2) IF NOT ERRORLEVEL 1 goto CORRECTO . 1. ejercicios.comandos cuando errorlevel<1 El siguiente código utiliza el errorlevel para comprobar si el disquete está introducido en la disquetera: @echo off :LEER vol A:\ >NUL 2>NUL if errorlevel 1 goto NO-DISCO REM aquí irían las operaciones a realizar sobre el diskete goto FIN :NO-DISCO echo Introduzca un disquete en la unidad A: pause goto LEER :FIN NOTA: Podríamos haber utilizado DIR. tras su ejecución. Este código suele ser 0 cuando la ejecución finalizó con éxito. y otro valor si hubo algún tipo de anomalía.comandos cuando errorlevel<1 :ALGUN_ERROR . devuelven un código de estado.¿Qué sucede si %1 es un directorio? ERRORLEVEL Casi todos los comandos. que es un número indicativo de cómo ha finalizado la ejecución del programa. Cuando el comando IF compara el errorlevel. nos devolverá 'true' cuando este sea superior o igual al número especificado. Es decir: IF ERRORLEVEL 3 comando equivaldría a: IF NOT ERRORLEVEL 3 comando equivaldría a: Los siguientes fragmentos de código tienen el mismo efecto: 1) IF ERRORLEVEL 1 goto ALGUN_ERROR . El siguiente programa en ensamblador lee una pulsación de teclado y almacena su código ASCII en la variable ERRORLEVEL: si (errorlevel >= 3) comando si (errorlevel < 3) comando . aunque si el directorio raíz está vacío también devuelve un errorlevel igual a 1. :FIN Códigos ASCII: A (65)... if errorlevel . B (66).Z:\>debug getch....función que retorna al programa llamante. goto MENU :CLIENTES .?. PROVEEDORES o FIN ..com No se encuentra el archivo -a 1517:0100 mov ah.aquí pulso la X mayúscula Z:\>echo %errorlevel% 88 Completar el siguiente archivo BAT que muestra un menú con varias opciones: @echo off :MENU cls echo elija opción echo A-Archivo de clientes echo B-Archivo de proveedores echo C-Finalizar getch if errorlevel .. c (99) 2. goto CLIENTES. Escribir un programa ping2.función que captura la pulsación de una tecla sin eco..bat que nos permite hacer un ping a múltiples hosts de una misma red.. 08 . a (97). if errorlevel . C (67). Nos mostrará un mensaje diciendo si el host está o no conectado: .. . :PROVEEDORES .?. con código de 15A6:0106 int 21 retorno el almacenado en AL 15A6:0108 -r cx CX 0008 :8 -w Escribiendo 00008 bytes -q Z:\>getch .?. PROVEEDORES o FIN .. b (98). 4C ......?.?... 1517:0102 int 21 almacena el resultado en AL 1517:0104 mov ah.?. goto CLIENTES. . que será distinta en cada caso.13 . Para discernir entre un host conectado y uno inalcanzable.conectado 10.1. su valor es %x% Ya existe la variable x.NO ESTÁ CONECTADO 192..1.0.conectado 192. independientemente de que nos respondan con un pong. diferentes a la igualdad: IF [/I] cadena1 op-log cadena2 comando Los operadores lógicos admitidos son: EQU . el errorlevel devuelto siempre es 0.conectado .0. debemos generar un errorlevel.conectado .168.55 .menor que o igual GTR .0. INDICACIÓN: MEJORAS en el IF Cuando las extensiones de comando están habilitadas. IF tiene mayor funcionalidad: a) Podemos preguntar por la existencia de variables: IF DEFINED variable comando C:\sirio>set x=25 C:\sirio>if defined x echo Ya existe la variable x. su valor es 25 b) Y realizar comparaciones lógicas..separa ELSE de los paréntesis por algún espacio ..0. 2. También admite la cláusula (opcional) ELSE: IF expr-lógica ( .NO ESTÁ CONECTADO 10. el grupo de comandos debemos encerrarlo entre paréntesis.conectado 10.5 . Mejorar el programa anterior.55 .mayor que GEQ .conectado 192.igual NEQ .sentenciaS TRUE ) ELSE ( <-..0.2 . por ejemplo buscando con FIND alguna palabra en la información mostrada por el PING.0. Cuando se hace ping a una IP.168.C:\>ping2 13 2 5 55 99 128 129 130 131 132 133 200 201 222 192.1.0 13 2 5 55 99 128 129 130 131 132 133 200 201 222 10.168.menor que LEQ . de manera que el primer argumento sea la red: C:\>ping3 10.2 .0.13 .168.0.1.0.5 .mayor que o igual /I indica que la comparación se hará case insensitive (ignora la diferencia entre MAYs y mins) c) Ahora el IF admite más de un comando.no igual LSS . En el siguiente programa: @echo off set VAR=basura echo antes del IF: %VAR% IF DEFINED VAR ( set VAR=CHATARRA echo en el IF: %VAR% ) echo después del IF: %VAR% su ejecución nos daría un resultado un tanto sorprendente: C:\prueba>prog antes del IF: basura en el IF: basura ¡¡ Pero si ya he cambiado el valor de la variable !! después del IF: CHATARRA La solución a este problema es utilizar lo que en palabras de µsoft se conoce como "expansión de variables retardada" (ver cmd /? y set /?): 1. Las variables que deseemos que se expandan en el momento preciso de su utilización las rodearemos con admiraciones (!). Debemos habilitarla (por defecto vienen deshabilitadas). para ello necesitamos abrir una subshell: cmd /v:on o bien introducir como primera instrucción del bat: SETLOCAL ENABLEDELAYEDEXPANSION 2.sentenciaS FALSE ) C:\>set a=Andorra C:\>set b=Barcelona C:\>IF a LSS b (echo %a% %b%) ELSE (echo %b% %a%) Andorra Barcelona Expansión retardada de variables Las variables comprendidas entre los paréntesis las expande en el momento de la llegada al IF: antes de ejecutar ninguna de las instrucciones interiores. El siguiente programa funcionaría correctamente: @echo off set VAR=basura echo antes del IF: %VAR% IF DEFINED VAR ( set VAR=CHATARRA echo en el IF (1): %VAR% .. bat @echo off for %%X in (%*) do echo %%X ^Z W:\>repite ms-dos es "bueno. comando Comando MS-DOS a ejecutar con cada elemento de la lista. ejemplo 1 -. no al iniciar la ejecución de la estructura for Bucles FOR Ejecuta el comando para cada uno de los elementos especificados en la lista: FOR %NombreVariable IN (lista) DO comando FOR %%NombreVariable IN (lista) DO comando <-. Si en la lista aparecen comodines ( ? o * ) el comando se ejecutará para cada uno de los archivos que cumplan la expresión regular. bonito y barato" ms-dos es "bueno.y desde un archivo bat: W:\>more > repite. C:\Documents and Settings\sirio\prueba>vprog antes del IF: basura en el IF (1): basura <-.for desde línea de comandos: W:\>for %x in (uno dos tres cuatro) do @echo %x uno dos tres cuatro -.Aquí he utilizado %VAR% en el IF (2): CHATARRA <-. bonito y barato" . (lista) Especifica un conjunto de elementos o archivos separados por coma.dentro de archivos BAT NombreVariable Un nombre de variable de un único carácter. que se utilizará para recorrer los elementos o archivos de la lista.desde línea de comandos <-. OjO: La variable diferencia si es MAYÚSCULA o minúscula.echo en el IF (2): !VAR! ) echo después del IF: %VAR% C:\Documents and Settings\sirio\prueba>cmd /v:on Microsoft Windows 2000 [Versión 5.2195] (C) Copyright 1985-2000 Microsoft Corp.y aquí !VAR! después del IF: CHATARRA NOTA: Este mismo problema se presenta en el FOR. la solución es la misma: expandir las variables en el momento de su utilización. punto y coma o espacio en blanco.00. ¿Se han borrado? ...NET.visualizamos los archivos del directorio actual punto.. NO directorios."] %V IN (archivo | 'comando' | "cadena") DO comando <-. En la elaboración de la lista sólo utiliza archivos.Lista con contador FOR /F ["tokens=. los documentos nunca desaparecerán. *.com %1\*. muestra los del raíz) @echo off FOR %%X IN (%1\*. . (Si no pasamos argumento.Volver al día siguiente y comprobar que las imágenes siguen ahí: aunque tiremos de la cadena 1000 veces..exe %1\*.png.odt net.bat) del directorio pasado desde línea de comandos. ejemplo 3 El siguiente archivo BAT nos lista todos los archivos ejecutables (.bat) DO echo %%X MEJORAS en el FOR Cuando las extensiones de comandos están habilitadas (por defecto lo están.jpg. Una curiosa forma de esconder documentos y que nadie los borre: en la basura.NOTA: Si las extensiones de comandos están habilitadas.txt Frases. C:\pruebas>for %f in (*.Con el parámetro /R ejecuta el comando recursivamente: C:\>for /R %x in (*) do @echo %x .. .exe.Vaciar la papelera desde Windows. . podemos suprimir las comillas de una variable con el símbolo ~ : for %%X in (%*) do echo %%~X (más información: for /?) ejemplo 2 Cuando aparece un * en la lista.Echar un vistazo a la papelera desde Windows ¿se ven? ¿Y desde MS-DOS? . lo interpreta como un comodín.Directorios FOR /L %V IN (inicio.com.jpg ejerci1. el comando FOR admite una serie de parámetros que amplían su funcionalidad: FOR /R [ruta] %V IN (lista) DO comando <-.Recursividad FOR /D %V IN (lista) DO comando <-.gif) do move %f C:\Recycled En el último ejemplo hemos movido las imágenes con formatos gráficos de internet a la papelera del disco C:. *.Recorrido de tokens en líneas de texto 1 . fin) DO comando <-. incremento.. y antes de aplicar el comando se creará una lista de archivos que cumpla con la expresión regular. delims=. más información: CMD /? ).gif . C:\pruebas>FOR %f IN (*) DO @echo %f <-. scf C:\WINNT\winhlp32..dll . C:\WINNT\discover. C:\WINNT\system32\mscoree. 3 ..exe C:\winnt\system32\wscript.C:\bat2exe..dll C:\winnt\vmmreg32..txt >NUL ^Z 1 archivos copiados.dll C:\winnt\twain_32. 2 .txt .Con el parámetro /L podemos crear el típico bucle por contador: FOR /L %NombreVariable IN (inicio salto final) DO comando podemos separar "inicio".exe .Con el parámetro /D recorre los directorios. cuyo nombre y cantidad especificamos desde línea de comandos: C:\pruebas>copy con crea.... en lugar de los ficheros: C:\>for /D %x in (*) do @echo %x WINNT Documents and Settings Archivos de programa prog .bat @ECHO OFF FOR /L %%A IN (1 1 %1) DO ECHO 2> %2%%A..dll C:\winnt\system32\mmc.exe C:\WINNT\explorer.dll C:\winnt\system32\msorcl32.exe) do @echo %x C:\winnt\twain.dll C:\WINNT\system32\aaaamon. ). "salto" y "final" por comas ( .exe C:\winnt\system32\javaws..dll C:\WINNT\system32\msorcl32. ) o punto y coma ( .dll C:\winnt\system32\mscoree.zip C:\LANGUAGE. C:\pruebas>crea 5 churro .dll *. Con el siguiente archivo bat creamos archivos txt vacíos..exe .com C:\editpad. Ejemplo 2: Visualizamos todas las dll y exe a partir de C:\WINNT: C:\>for /R C:\winnt %x in (*. txt) do @echo %x El que la coplas El for va recorriendo todas las líneas.168. 1.168. X:\>for /F %x in (fich.txt El corazón y el cerebro. 255) DO ping -n 1 %RED%%%H | FIND "TTL=" ^Z C:\pruebas>pingred Respuesta desde 192. FOR /L %%H IN (1.25: bytes=32 tiempo<10ms TTL=64 4 .txt churro2.1: bytes=32 tiempo=1ms TTL=128 Respuesta desde 192.168. Los distintos tokens se irán guardando en nombres de variable alfabéticamente consecutivas a partir de la variable utilizada en el for: En el siguiente ejemplo nos quedamos con los tokens (palabras) 1. las dos grandes vísceras que se llevan la primacía de los sentimientos y de la razón.1.txt churro3.txt churro4.txt El siguiente archivo BAT.Con el parámetro /F podemos recorrer: a.1.22: bytes=32 tiempo<10ms TTL=64 Respuesta desde 192. tokens Podemos seleccionar varios tokens mediante la cláusula tokens=.el resultado de la ejecución de un comando c.168. son las que presiden el arranque de las coplas de Jorge Manrique a la muerte de su padre.txt churro5.13: bytes=32 tiempo<10ms TTL=64 Respuesta desde 192. 3 y 5 de cada línea: .una cadena A) ARCHIVO X:\>type fich.1. y cada línea se ha dividido en "tokens" (por defecto: token=palabra).1. hace un ping a broadcast.168.bat @ECHO OFF SET RED=192. La variable del for almacena el primer token de cada línea.C:\pruebas>DIR CH* /B churro1. mostrando sólo la direcciones de aquellos que contestan: C:\pruebas>more > pingred.1.un archivo b. las dos grandes vísceras ] [ que se llevan la primacía de los sentimientos y de ] [ la razón.txt) do @echo [ %m ] [ El corazón y el cerebro.y nos quedamos con el primer token: X:\>for /F "delims=. en el siguiente ejemplo nos quedamos con las 3 primeras palabras y la 5: X:\>for /F "tokens=1-3. son .txt) do @echo [ %K ] [ El corazón y el cerebro..llevan . Y si queremos toda la línea. que se llevan .que coplas . son las que presiden el arranque de las ] [ coplas de Jorge Manrique a la muerte de su padre. Podemos modificar los delimitadores con la cláusula delims= En el siguiente ejemplo anulamos los delimitadores y obtenemos lo mismo de antes: X:\>for /F "delims=" %K in (fich.cerebro. coma. las dos grandes vísceras ] [ que se llevan la primacía de los sentimientos y de ] [ la razón.txt) do @echo %m El corazón y el cerebro que se llevan la primacía de los sentimientos y de la razón .y .a Y si deseamos la línea completa a partir de la 7ª palabra: X:\>for /F "tokens=7*" %A in (fich. pues para separarlos se han utilizado el espacio en blanco y la tabulación.a Podemos escoger rangos.5" %i in (fich.5" %a in (fich.primacía la . seleccionaremos todos los tokens de cada línea: X:\>for /F "tokens=*" %m in (fich.cerebro.. y dos puntos) .%d El corazón y .%k El . punto y coma. son las que presiden el arranque de las ] [ coplas de Jorge Manrique a la muerte de su padre.txt) do @echo %A %B dos grandes vísceras los sentimientos y de el arranque de las muerte de su padre.Jorge .no debe haber espacios entre ellos.X:\>for /F "tokens=1.txt) do @echo %i .primacía la razón. que .3.:" %m in (fich.%j . ] delimitadores En los ejemplos anteriores los "tokens" coincidían con las palabras. ] Utilizamos como delimitadores los signos de puntuación (punto.que coplas de Jorge .son .txt) do @echo %a %b %c . ('cadena') .bat Ejecuta: ren backup. o eol=carácter.DIF f: ruta completa s: short name C:\DOCUME~1\sirio\EXCURS~1.TXT C:\DOCUME~1\sirio\ABC~1.bat 20060219-backup. o useback que cambia la semántica de la lista: (`comando`) .2. Por ejemplo: C:\Documents and Settings\sirio>for %x in (*) do @echo %~fsx C:\DOCUME~1\sirio\mueve. (archivo) ("archivo1 archivo2 archivo3") B) COMANDO El funcionamiento es similar al de los ficheros.3 delims=. C) CADENA Con el siguiente comando añadimos la fecha a un nombre de archivo: X:\>type rdate.txt) do @echo %M %N %O Y utilizar otras cláusulas. que interpreta las líneas que comienzan por ese carácter como líneas de comentario y no serán procesadas.bat C:\DOCUME~1\sirio\TEMPFI~1. únicamente que tendremos que encerrar el comando con comillas simples: X:\>for /F "tokens=15 delims=: " %x in ('ipconfig ^| find "IP"') do set myIP=%x x:\>set myIP myIP=192.coplas de Jorge Manrique a la muerte de su padre Podemos combinar delimitadores y tokens: for /F "tokens=1. como skip=nº.TXT C:\DOCUME~1\sirio\HID~1 C:\DOCUME~1\sirio\FONTS~1.33 Observar el carácter de escape ^ necesario para que el pipe lo interprete dentro del comando en lugar de ser interpretado para el FOR.TXT C:\DOCUME~1\sirio\EXCURS~3.168.bat tempfile.TXT C:\DOCUME~1\sirio\DIAD~1.TXT C:\DOCUME~1\sirio\EXCURS~2. empezando a procesar en la n+1.bat for /f "tokens=2-4 delims=/ " %%W in ("%date%") do ren %1 %%Y%%X%%W-%1 X:\>rdate backup.diff .CAC C:\Documents and Settings\sirio>for %x in (*) do @echo %x mueve.bat FORMATOS DE SALIDA Podemos especificar un formato para la variable del for..:" %M in (fich..1. que se saltaría las n primeras líneas del archivo. ) . Podemos consultarlos todos ejecutando for /? Acortar direcciones: Cuando usamos un for para recorrer los archivos nos devuelve la dirección entera del archivo.Excursiones.fonts. Siempre se usara %~ seguido de una letra que representa lo que queremos obtener (el nombre. En el caso por ejemplo de que la variable X tenga la dirección de un archivo y solo quisiéramos saber su extensión.txt Excursiones del año 2005.hid . @echo off FOR /R %%X in (*) DO ( echo Nombre: %%~nX echo Extension: %%~xX echo Tamaño: %%~zX echo. este programa nos mostrara algunos datos de los archivos que existan en la misma carpeta y directorios superiores. Las letras que podemos usar son: • • • • • • • • • f Ruta y Nombre d Nombre Unidad donde se encuentra p Solo ruta n Solo nombre x Extensión s Ruta abreviada a Atributos t Fecha y hora de creación z Tamaño del archivo Por ejemplo.cache-1 O simplemente %~X. cuando lo que queremos es solo su nombre.txt dia D. Ahora les voy a enseñar una técnica para acortar esas direcciones. que elimina las comillas (si las tuviera) como vimos arriba. o saber su ubicación. la extensión. usaríamos: %~Xx y si quisiéramos saber en que unidad se encuentra: %~dX Para entender un poco mejor esto. etc) y por ultimo el nombre de la variable. miremos esto como una sintaxis.txt Excursiones del año 2004. Esto es molesto.txt .txt A B C. El siguiente programa debería contar el número de veces que aparece la palabra %2 en el fichero %1: @echo off set cont=0 for /f "tokens=*" %%L in (%1) do ( for %%P in (%%L) do ( if /I "%%P"=="%2" set /A cont=%cont%+1 ) ) echo En %1 aparece %cont% veces la palabra %2 Pero la ejecución siempre nos da el mismo resultado: Z:\pruebas>cuenta Quijote. donde las variables que deseemos que se sustituyan en el mismo instante de su utilización las encerraremos con admiraciones. podemos añadir como primera línea: SETLOCAL ENABLEDELAYEDEXPANSION Subrutinas: Llamar a un fichero BAT desde otro fichero BAT Desde un fichero BAT podemos invocar la ejecución de otro fichero BAT (subrutina) de varias formas: . y ya no se modifica hasta que finaliza el bucle for o la agrupación de sentencias.Expansión de variables retardada Cuando aparecen variables de entorno en las estructuras IF y FOR. con sustitución de variables retardada. Deberemos cambiar la línea anterior por: if /I "%%P"=="%2" set /A cont=!cont!+1 Y ejecutar el programa en una shell con susitución retardada: cmd /v:on Aunque si deseamos que el programa bat se ejecute por defecto.txt sancho En Quijote. su valor es calculado al inicio de éstos.txt aparece 0 veces la palabra sancho Pues la variable cont se sustituye por su valor (0) al entrar en el bucle y siempre estoy ejecutando la instrucción: if /I "%%P"=="%2" set /A cont=0+1 Por lo que el resultado final del programa será 0 ó 1 (depende de si el último IF de todos es cierto o no) La solución es utilizar una shell con "sustitución de variables retardada". . <-. se continúa con la ejecución del programa principal.la subshell hereda las variables de entorno . En el programa "principal. variable x: PRINCIPAL variable x: SUBPROGRAMA finalizando el subprograma Z:\pruebas>set x x=SUBPROGRAMA --. variable x: PRINCIPAL variable x: SUBPROGRAMA finalizando el subprograma VARIABLE X: PRINCIPAL FIN PRINCIPAL cmd /c rutina <-..bat".. por finalizada la ejecución del programa bat que realizó la llamada (es como un GOTO sin retorno).bat @echo off echo INICIO PRINCIPAL set x=PRINCIPAL rutina echo VARIABLE X: %x% echo FIN PRINCIPAL El resultado de la ejecución sería: Z:\pruebas>principal INICIO PRINCIPAL ejecutando el subprograma . con los siguientes archivos bat: --.bat @echo off echo ejecutando el subprograma .principal.. Cuando finaliza la subrutina.. todas las variables de entorno que defina en la subrutina se pierden al volver a la shell principal. Por ejemplo.. echo variable x: %x% set x=SUBPROGRAMA echo variable x: %x% echo finalizando el subprograma ( se han ejecutado en la misma shell ) 2: Ejecución en subshell: se abre una subshell donde se ejecutará el subprograma: cmd /c progbat2 Al abrirse una nueva subshell.rutina. cambiamos la línea de llamada por: El resultado de la ejecución es: Z:\pruebas>principal INICIO PRINCIPAL ejecutando el subprograma ...las variables de la shell principal NO se ven afectadas por lo que hagamos en la subshell 3: Ejecución en la misma shell: Se utiliza el comando CALL progbat .1: Llamada sin retorno: Escribiendo el nombre de otro archivo bat En este caso el control se transfiere de un programa bat a otro. . cuando finaliza la subrutina. %2.g. la sintaxis general de la llamada con CALL sería de la forma: CALL [pathTo]subprograma [arg1 arg2 ... los parámetros del subprograma (%1. y por tanto podemos pasarle parámetro posicionales. Podríamos poner también la la típica goto:FIN... :nombre_subprograma . . afectan al programa principal.. continúa la ejecución en el progama principal.) son independientes. variable x: PRINCIPAL variable x: SUBPROGRAMA finalizando el subprograma VARIABLE X: SUBPROGRAMA entorno FIN PRINCIPAL <-.] Y aunque se ejecuten en la misma shell. otros subprogramas) Todo se ejecuta en la misma shell. Por ejemplo. por lo que puede hacerse necesaria la instrucción goto :eof .por aquí puede haber más código que no pertenece al subprograma (e... . Las sentencias del subprograma se ejecutan secuencialmente hasta llegar al final del archivo. que continúa la ejecución al final del archivo (end of file). aunque los argumentos recibidos en los parámetros posicionales %1. Si en el programa principal anterior sustituimos la llamada por CALL rutina obtenemos: Z:\pruebas>principal INICIO PRINCIPAL ejecutando el subprograma . por tanto las modificaciones hechas en el entorno desde el subprograma.Ejecuta la subrutina y el programa principal en la misma shell... %2. ] . goto :eof REM ..se han visto afectadas las variables de del programa principal PASO DE ARGUMENTOS AL SUBPROGRAMA En cualquiera de los tres casos anteriores estamos ejecutando un programa bat. MEJORAS en el CALL Llamar a una subrutina dentro del mismo archivo Con CALL también podemos llamar a una etiqueta como si se tratara de una función o subrutina: CALL :nombre_subprograma [ arg1 arg2 .. no son compartidos entre la parte principal y la subrutina. listaaaa [ CONVIERTE ESTO A MAYÚSCULAS.siendo la etiqueta :FIN la última línea del programa.sustituimos todas las 'a' minúscula por 'A' mayúscula <-. O incluso EXIT /B nº . En la subrutina sólo será necesaria si hubiera código debajo de ésta. LISTAAAA ] ...bat @echo off set /P x="Dime algo: " call :toUpperCase %x% echo [ %x% ] exit /b :toUpperCase set x=%* set x=%x:a=A% set x=%x:b=B% set x=%x:c=C% set x=%x:d=D% set x=%x:e=E% set x=%x:f=F% set x=%x:g=G% set x=%x:h=H% set x=%x:i=I% set x=%x:j=J% set x=%x:k=K% set x=%x:l=L% set x=%x:m=M% set x=%x:n=N% set x=%x:ñ=Ñ% set x=%x:o=O% set x=%x:p=P% set x=%x:q=Q% set x=%x:r=R% set x=%x:s=S% set x=%x:t=T% set x=%x:u=U% set x=%x:v=V% set x=%x:w=W% set x=%x:x=X% set x=%x:y=Y% set x=%x:z=Z% set x=%x:á=Á% set x=%x:é=É% set x=%x:í=Í% set x=%x:ó=Ó% set x=%x:ú=Ú% <-.. si necesitamos devolver un código de retorno (errorlevel). El siguiente ejemplo es una demostración de cómo podría convertirse a mayúsculas : Z:\pruebas>type mayuscular. Z:\pruebas>mayuscular Dime algo: Convierte esto a mayúsculas. Estas son las variables mas usadas: Citar %ALLUSERSPROFILE% C:\Documents and Settings\All Users configuración para todos los usuarios) (Ruta de la carpeta con la (Ruta de la %APPDATA% C:\Documents and Settings\{usuario}\Datos de Programa carpeta con datos de programa) %COMPUTERNAME% %COMSPEC% Nombre del equipo (Nombre del equipo) C:\Windows\System32\cmd.WSH.VBE.BAT. .EXE. .:Computer (Nombre de usuario actual) 31/12/2009 (Fecha actual) 00:00:00. .COM.2.WSF. .CMD.00 (Hora actual) C:\ (Carpeta actual con su ruta completa) 0 o 1 (Código de salida del comando anterior) 32767 (Número aleatorio de 0 a 32767) %ERRORLEVEL% %RANDOM% .VBS.JS . . .Variables Para ver todas las variables usamos el comando set. (Extensiones de archivo ejecutables) %PROGRAMFILES% programa) %PROMPT% C:\Archivos de programa (Ruta de la carpeta archivos de $P$G (Formato del intérprete de comandos) C: (Unidad en la que se ha instalado Windows) (Contiene la carpeta de Windows) %SYSTEMDRIVE% %SYSTEMROOT% y %WINDIR% C:\Windows %TEMP% y %TMP% Temp) %USERNAME% %DATE% %TIME% %CD% C:\DOCUME~1\{usuario}\LOCALS~1\Temp (Ruta de la carpeta Ej. .exe ( Ruta al intérprete de comandos) (Unidad en la que se %HOMEDRIVE% Unidad donde estan los datos del usuario (C:) encuentra los datos de usuario) %HOMEPATH% actual) %USERPROFILE% %PATH% ejecutables) \Documents and Settings\{usuario} (Ruta a la carpeta del usuario C:\Documents and Settings\{usuario} (incluye unidad) C:\Windows\System32\. . Si escribimos set y luego enter veremos todas las variables.C:\Windows\ (Rutas en la que se buscan %PATHEXT% . usando: dir /a "%homedrive%%homepath%\Escritorio". el que abra el . Citar %nombrevariante:~numerosdecaracteresanteriores.4% %original:~2% %original:~-3% %original:~0. A las variable se las señala con %% ejemplo para indicar la variable homepath escribiremos %homepath%.5 sino 1 (redondea hacia abajo) Para mas información sobre variables set/? 2. asi que si hacemos 3/2 no nos dara 1. Citar Set /p variable= No hay valor porque el valor lo define el usuario. tenemos que ver cuantas letras hay detras de la f en este caso serian 5 (abcde) y cuantos caracteres ocupa lo que queremos ver en este caso serian 4 (fghi).Recortar una variable Podemos tomar un trozo de una variable por ejemplo: Hay una variante llamada original y su valor es abcdefghijk Si queremos solo tener las letras fghi. Por ejemplo podemos listar el contenido del escritorio sin estar en el.1.numerosdecaracteresqueabarca% En el ejemplo anterior seria (nos mostraria solo fghi) Ahora queremos mostrar a partir de la c incluida Ahora queremos mostrar los ultimos 3 caracteres Ahora queremos mostrar todo menos los ultimos tres caracteres %original=~5.bat Para definir variables como el resultado de sumas restas multiplicaciones divisiones. Citar Set /a variable=numero+numero Set /a variable=numero-numero Tambien si una variable es un valor numero podemos operar con ella por ejemplo Código: DOS Set /a variable=%random%*%random% En este lenguaje Batch no tenemos soporte para comas. por las dudas siempre que nos referimos a una ruta usaremos comillas dobles "".Las variables nos sirven para indicar un valor que puede ser un numero una ruta o lo que queramos. en donde escribimos la variable estamos escribiendo en realidad el valor de la variable.-3% . Para establecer una variable hacemos Set variable=valor En variable el nombre de nuestra variable y en valor lo que queremos que valga la variable En el bat para que la variable la defina el usuario hacemos. Elimino la premisa (0alineado_1firmado_) copy %uno%.* del 0alineado*.-7% . @ echo Si deseas historial redirecciona la salida a un archivo @ echo . @ pause rem eliminamos forzando borrado del 1firmado*. @ echo Este archivo BAT sobreescribe los apk originales dentro de esta carpeta.-5% rem @ echo Los cuatro ultimos numeros son %mia:~6% rem @ echo Los tres primeros numeros son %mia:~.apk %dos:~19%. @ echo .pem testkey. @ echo.jar testkey.x509.* /F /Q rem Ahora firmamos con signapk FOR %%f IN (*.apk) DO call:label %%~nX rem fin de bucle FOR goto:fin :label set uno=%1 set dos=%uno% rem renombro con copy forzando sobreescribir.* echo programa terminado rem Ejemplo de recortar cadenas de caracteres en variables. @ echo Copia los apk deoxdexados en este directorio antes de empezar.apk) DO java -jar signapk. @ echo Haz copia de los mismos antes de ejecutarlo. @ echo . @ set mia=1234567890 rem @ echo El numero central es %mia:~4.pk8 %%f 1firmado_%%f rem Ahora alineamos con zipaling FOR %%h IN (1firmado*. @ echo pulsa "ctrl+c" si deseas terminar la ejecucion @ echo .apk /Y rem informo fin de etiqueta para retorno a comando FOR goto:eof :fin del 1firmado*.* /F /Q del 0alineado*.Para hacer el signo ~ lo hacemos con alt+126 @ echo .apk) DO zipalign -v 4 %%h 0alineado_%%h rem paso parametros a la etiqueta label @ FOR /R %%X in (0alineado*. Espero que les guste! que .dll :: Bat que borra 4 ultimos caracteres de los nombres de varios archivos aceptando archivos incluyan nombres con espacios. Luego publicaré algunas cosillas más. @echo off set ext=xls rem ext es la extension de los archivos sin anteponer punto. :: Ubicar este bat en la misma carpeta de los archivos a renombrar.%ext% if "%newname%"==".-%sacar%%%.%ext%') do call :lab %%f exit :lab set original= set original=%* set newname= call set newname=%%original:.%ext%=%% call set newname=%%newname:~0.%ext%" (goto :eof) ren "%original%" "%newname%" goto :eof Hoy les traigo un tutorial sobre el comando set con algunos descubrimientos.pause ------------------------------------------------------------------------------for /F %%M in ('dir *. set sacar=4 rem sacar es la cantidad de letras al final del nombre que quieres sacar.apk /B /S') DO call:label %%M %%~dM %%~pM %%~nM %%~xM rem fin de bucle FOR goto:fin :label set uno=%1 set unidad=%2 set ruta=%3 set nombre=%4 set nombre_recortado=%nombre:~4% set extension=%5 rem copio archivo modificado el nombre copy %uno% %unidad%%ruta%%nombre_recortado%%extension% /Y rem borro archivo original del %uno% /F /Q rem informo fin de etiqueta para retorno a comando FOR goto:eof :fin @ echo FIN DEL PROGRAMA --------------------------------------------------------------------------------:: CarlitoS. for /f "tokens=*" %%f in ('dir /b /a *. d=4 a) set /a a=1.bit a bit y ^ . Si se especifica una variable que no está definida en el entorno actual. () . para declarar varias variables (siempre que sean numéricas).b=a+1. c=1.c=3.operadores unarios */% . pero también sirve) b) set /a a=b=c=d=1 c) set/aa=b=c=d=1 (también funciona de esta manera para los que quieran ahorrarse 2 bytes) 2) Declarar a=1.b=2.separador de expresiones Cualquier cadena de la expresión que no sea numérica.c=1.bit a bit exclusivo o | . Ejemplos: 1) Declarar a=1.bit a bit = *= /= %= += -= . además queremos que b sea 2 veces a y así.operadores aritméticos << >> . d=2*c (No conocemos a pero suponemos que está declarada. . a) set /a a=(b=2)+(c=4) 5) Declarar b=2*a . Esto generalmente lo vamos a usar en un fichero BAT).agrupar !~. b=1.asignación &= ^= |= <<= >>= . utilizando el comando set y el modificador /a (set /a) una sola vez y en una sola línea.Autor: Tempestinfinit Fecha: 13/10/2009 Tema: Comando Set Separador de expresiones mediante el comando set (set /a): Se puede utilizar el separador de expresiones o la (. c=2*b .c=b+1.) como se encuentra explicado en la ayuda del comando Set.d=c+1 4) Declarar a=(b=2 y c=4) y luego a=(b+c).d=1 (esto generalmente se usa cuando tenemos varios valores. b=2.d=4 3) También podemos incluir variables no declaradas anteriormente (siempre y cuando las variables sean declaradas mientras se realiza la operación con ellas sino se tomarán como 0). Nota: a. c=3. b y c no fueron declaradas antes. d=1 a) set /a a=1.operadores aritméticos +. . se usará el valor cero.desplazamiento lógico & .b=1. a) set /a a=1. se tratará como variable de entorno cuyo valor se convertirá a tipo numérico antes de usarse. no se puede hacer (al menos no sin obtener un error). a) set /a dia=%date:~0. Declaramos a=1.longitud% %ABC:~6.c=2*b.mes=%date:~3.abc=a*100+b*10+c Subcadenas: Declaramos ABC=abcdefghijklmnñopqrstuvwxyz %ABC:~desplazamiento.5% (desplaza 6 caracteres y muestra 5 a partir del 6to) ghijk %ABC:~10% (desplaza 10 y sino se especifica la longitud utiliza el resto de la cadena como longitud) klmnñopqrstuvwxyz Si algún número (desplazamiento o longitud) es negativo. c=3 y asignamos a. si no sabemos cuantas cifras tiene el número en la variable que queremos asignar. Esto conlleva a la complicación de que.-2% (muestra todos menos los últimos 2) abcdefghijklmnñopqrstuvwx %ABC:~-2% (desplaza 0 muestra los últimos 2) yz Anteriormente si queríamos obtener la fecha o la hora en 3 variables utilizando una sola línea debíamos hacer esto: set dia=%date:~0. %ABC:~-10% (extrae los 10 últimos) qrstuvwxyz %ABC:~0. a) set /a abc=(%a%%b%%c%) . entonces el número usado es la longitud del valor de la variable de entorno agregado al desplazamiento o longitud especificados. 7) Declaramos a=1. b=2 y c=3.2%.año=%date:~-4% 9) Obtener la hora en 3 variables utilizando un solo set /a (se complica un poco más). o sea.d=2*c 6) Podemos utilizar variables declaradas anteriormente para asignarlas a otras variables.(recuerden que a.-5% & set año=%date:~-4% Ahora: 8 ) Obtener la fecha en 3 variables utilizando un solo set /a. b y c a abc.a) set /a b=2*a. . Esto es puramente matemático y no hay otra manera al menos de declarar 3 variables y luego asignar a una cuarta (al menos no en una línea).2% & set mes=%date:~3.-5%.b=2.b=2. b=2. se ubica al principio de la cadena y muestra 10) abcdefghij %ABC:~0.c=3. a) set /a abc=(a=1.-10% (extrae los 10 primeros.c=3. b y c tienen que estar declaradas).a*100+b*10+c) b) set /a a=1. 2%. no existe? :XD se supone que esta en el medio de las dos a) Ahora viene lo interesante! Declaramos las siguientes variables: 1) set /a "ð+=1" 2) set /a "ÿ+=1" 3) set /a "HolaÿaÿtodosÿsoyÿTempestBP+=1" Resultado: 1) 1 .a) set /a hora=%time:~0. Ejemplo: set /a trata de aprender+=1 (esto da error) set /a trata-de-aprender+=1 (esto da error) Entonces se me ocurrió utilizar los caracteres ð(representa al guión) y ÿ( representa al espacio en blanco) para sustituirlas por el espacio en blanco tradicional y el guión.-5%.2%.2%. Ejemplos: Declarando variables..seg=a*100+b Sustitución de variables: Con el comando set y el modificador /a (set /a) podemos realizar sustituciones simples y compuestas(con algunas excepciones) de subcadenas y recuerden que siempre con el modificador /a hablamos de números.(%a:789=8910%) (Sustituímos 123 por 456.min=%time:~3.mes=%date:~3. 456 por 789 y 789 por 8910) 4564568910 Sumando variables con espacios o guiones: Si queremos sumar variables con espacios o con guiones no se podría.b=%time:~-2%.a=%time:~6%..-6%.seg=a*100+b 10) Incluso si queremos combinar la 8 y la 9 para ahorrarnos un set /a podemos. a) set /a dia=%date:~0.año=%date:~-4%. Algunos ejemplos: a) Declaramos a=123456789 set /a a=%a:123=999% (Sustituímos la subcadena numérica 123 por 999) 999456789 b) set /a a=(%a:123=456%).min=%time:~3. hora=%time:~0.-6%.b=%time:~-2%. de manera de poder sumar una variable que contengan espacios en blanco y guiones.a=%time:~6%. 1) set "tempest=ÿ" 2) set "varnula=^" Resultado: 1) a a (se encuentra en medio de las dos a) 2) aa (variable nula.(%a:456=789%). (%a:789=7890%) (También podemos incluir el comando set) Llamadas a etiquetas: Esta técnica nos permite hacer una llamada a una etiqueta y luego al finalizar continuar declarando el resto de las variables. Ejemplo: @echo off set a=123456789 set /a a=(%a:123=456%)&call:C1. realmente como lo que son. en fin. . de manera que pueden utilizarse para trabajar en memoria.(%a:456=789%)&call:C2.(%a:789=7890%)3-OK 1-OK. la ayuda del DOS nos dice: Los valores numéricos son números decimales..(123789789)2-OK. los dos caracteres que utilicé al mostrarse con el comando echo representan el espacio y el guión. ya que no tiene sentido pensar en nada.(%a:456=789%)&pause.(%a:456=789%). y lo mismo que 022.(%a:789=0%)&call:C3 :C1 echo Trata de goto :eof :C2 echo aprender todo goto :eof :C3 echo lo que puedas Trata de aprender todo lo que puedas Errores: Se produce un error con algunos números que creo empiezan con 0. Sin embargo al redireccionarlos a un archivo de texto.(123456789)3-ok b) set /a a=(%a:123=456%)&pause.(%a:789=7890%)&pause (Incluimos una pausa entre cada sustitución) c)set /a a=(%a:123=456%)&set b=. y 0 para los números octales.(%a:456=789%)2-OK. los muestra como ÿ y ð. Ejemplos: Declaramos a=123456789 a) set /a a=(%a:123=456%)&echo 1-OK.. De esta manera 0x12 es lo mismo que 18. a no ser que lleven el prefijo 0x delante para los números hexadecimales. Incluyendo comandos entre las sustituciones..2) 1 3) 1 Conclusión: Obviamente el espacio en blanco no existe. O bien el programa ping. y Windows no es una excepción.cmd.exe -o incluso un visual basic. Igualmente existen muchos comandos que son sólo de consola.exe) o bien es un programa con extensión .exe. No es nada más que un área donde se guardan ciertas variables con su contenido. que puede generarse con el simple cuaderno de notas. Por ejemplo: set var=%var:cómo=que tal% con lo cual el contenido habría quedado modificado. Aunque esta es la definición clásica. Por ejemplo: set var=hola cómo estás Ejecutad para verlo: echo %var:cómo=que tal% Igualmente podríamos asignárselo de nuevo a “var” o bien a otra nueva variable de entorno. no quiere decir que “use” el mismo que el programa padre. Los entornos se heredan. mediante comandos. Si “str1″ figura varias veces se cambiará todas las veces en la cadena de caracteres. LENGUAJE DE COMANDOS – SCRIPTS .que no use la interfaz gráfica y que por tanto esté orientado a la consola. tienen un área de datos llamada “entorno”.Nota: la notación octal puede ser confusa: 08 y 09 no son números válidos porque 8 y 9 no son dígitos octales válidos. es un programa más) cuando se lanza. el “loader” -cargador. no debemos perder de vista que desde una consola de comandos podemos realizar.CMD . cmd.bat o . “hereda” dicho entorno. y cuya extensión es . Cada programa (y el propio intérprete de comandos.BAT ¿Qué es un script en lenguaje de comandos? No es nada más que un fichero de texto. En ese caso la cadena str1 dentro de la variable var quedará eliminado. o las tareas de mantenimiento que realizamos en Windows se pueden hacer desde una consola de comandos. prácticamente todo lo que la imaginación nos permita. Este programa (de consola) nos da la configuración TCP/IP de la máquina. Es importante entender que cada programa de Windows tiene su entorno (igual o diferente a otro programa). Todo lo que se configura. NOTA1: puede omitirse “str2″. Un ejemplo clásico es el programa ipconfig. Por ejemplo: set var=12345xx6 set var=%var:xx=% echo %var% NOTA2: se cambiarán todas las ocurrencias de “str1″.del sistema operativo realiza una copia del entorno padre en una nueva área de datos y al lanzar el programa le da como .com o . un literal por otro: %var:str1=str2% Este comando buscará todas las ocurrencias de la subcadena “str1″ dentro de “var” cambiándolas por “str2″. Su contenido son los comandos que ejecutaríamos en una consola de comandos (cmd) y cuyo fin es evitar las tareas repetitivas que podríamos realizar en una consola de comandos. Por heredar. Sustituir dentro de una cadena. ENTORNO DE UN PROGRAMA Todos los sistemas operativos. en este caso el cmd. sino que al lanzarse. Revisemos un poco la tipología de los comandos: un comando es “algo” que o bien entiende directamente el shell (el intérprete de comandos. lo cambia en el entorno del programa.…. existen dos entornos: uno del sistema y uno de usuario.. sino también definir. al ejecutarlo desde un cmd. cada .exe) y tecleando el comando “set” (sin comillas). NOTA: Realmente.CMD. bien con botón derecho en Mi PC / propiedades / pestaña de opciones avanzadas / botón de variables de entorno. es decir.BAT.. borrar su contenido y algunas opciones más. El sistema operativo al cargarse predefine ya una serie de variables de entorno.exe (y sólo de él.. en el caso anterior..exe FP_NO_HOST_CHECK=NO HOMEDRIVE=C: HOMEPATH=\Documents and Settings\mi usuario NUMBER_OF_PROCESSORS=1 OS=Windows_NT Path=C:\WINDOWS\system32.. nos dará algo similar a: ALLUSERSPROFILE=C:\Documents and Settings\All Users APPDATA=C:\Documents and Settings\mi usuario\Datos de programa CommonProgramFiles=C:\Archivos de programa\Archivos comunes COMPUTERNAME=MIMÁQUINA ComSpec=C:\WINDOWS\system32\cmd.JS. simplemente podemos ejecutar: echo %COMPUTERNAME% Esto nos dará como resultado: MIMÁQUINA Igualmente podríamos cambiarlo con el comando set citado anteriormente: set COMPUTERNAME=nuevoNOMBRE Pero… * ¿Esto realmente tiene el efecto de cambiar el nombre del ordenador? por supuesto que no.COM. dentro de una consola de comandos o bien dentro de un script se referencian para poder ver su contenido encerradas entre símbolos de %. si tuviésemos lanzadas dos consolas de comandos. cambiar. implica que cambia el entorno del cmd.VBE. en la copia del entorno original heredado por el programa.EXE. lanzando el intérprete de comandos (cmd. pero la visión de ambos es el conjunto de los dos..etc PATHEXT=.C:\WINDOWS\System32\Wbem. Esto sólo cambia el contenido de dicha variable. Este comando nos permite no sólo ver todas las variables. ya que lo que haría es modificar su propio entorno: la copia del entorno original del programa padre. Por ejemplo.VBS. Acabamos de ver nuestro primer comando: “set”. En nuestro caso. aunque lo veamos en conjunto. Si lo ejecutamos por consola..C:\WINDOWS..WSH PROCESSOR_ARCHITECTURE=x86 PROCESSOR_IDENTIFIER=x86 Family 6 Model 7 Stepping 3. o bien de una manera más simple..JSE.dirección del área de entorno esa nueva copia del entorno del “padre”. es decir. GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=0703 ProgramFiles=C:\Archivos de programa …etc… Fijémonos que la estructura es: nombre de variable=contenido de la variable Las variables.exe. para ver el contenido de la variable COMPUTERNAME. Podemos verlas. cualquier modificación en las variables de entorno dentro de un programa no afecta al sistema ni al resto de programas. ¿Dónde lo cambia? pues tal y como hemos comentado anteriormente. En otras palabras.WSF.. y le asignará el contenido de “prueba”. la expresión: set i=%n%/4 no hubiese realizado la operación matemática y se hubiese quedado con el contenido (como literal) de: 234/4 es decir.exe. Si ahora damos el comando “set” que nos muestra todas las variables.una de ellas con cmd. si recordamos que un programa hereda una copia del entorno del programa que lo lance. el cual era el texto “prueba”. set otra= En este caso borrará la variable. por supuesto. por curiosidad en este último caso y se puede ir realizando una prueba en una consola de comandos. se puede. La manera es con el modificador /a. sólo se cambiaría en el cmd. * ¿Podemos tener contenidos numéricos y no sólo alfabéticos. Es necesario el modificador /a. * ¿Cómo podemos crear una nueva variable de entorno? tan simple como darle un nombre y asignarle su contenido. esto implicará que todo lo que lancemos desde esa consola de comandos. Por ejemplo: set otra_de_nuevo=Esto es una %nuevo% de concatenación El resultado de lo anterior será que la variable “otra_de_nuevo” contendrá el valor “Esto es una prueba de concatenación”.exe que hayamos ejecutado ese comando “set”). de una variable de entorno llamada “nuevo”. y por tanto realizar operaciones matemáticas con el comando set? sí. set otra=%nuevo% Esto creará la variable “otra” con el contenido de la variable “nuevo”. * ¿Podemos asignar a una variable el contenido de otra?: sí. Simplemente recordando que el contenido de una variable es precisamente el nombre de la variable encerrada entre símbolos %. o modificará el contenido si existiese. Si después de ejecutar el comando anterior realizamos: echo %otra% su resultado será: prueba * ¿Cómo podemos borrar -eliminar. tendrá el contenido de esa variable modificado. Fijémonos. Pongamos un ejemplo: set n=234 (asignar 234 a la variable “n”) set /a i=%n%/4 Veremos que esto nos devuelve por pantalla el valor 58 (es decir la división de 234/4) y además se lo asigna a la variable “i”.una variable? simplemente no asignando nada. una cadena de caracteres con ese contenido y no con el resultado matemático de la división. Realicemos: set n=234 . Y ¿para que puede servir? simple. la variable “otra” ya no aparecerá. * ¿Puedo concatenar textos con variables en una asignación?: Sí. ya que si no lo hubiésemos puesto. Por ejemplo: set nuevo=prueba Esto creará si no existe. por supuesto. =. Cuando lo metemos y tecleamos “intro”. evitar usar. O bien. Es decir. Pongamos un ejemplo. es decir “y” en castellano) se interpreta como un “y”.set i=%n%/4 echo %i% veremos entonces: 234/4 Si ahora realizamos: set /a j=%i% ¿Que contendrá? ¿Contendrá el literal de texto “234/4″? ¿O sólo “234″ ya que el carácter “/” no es numérico? ¿O contendrá “58″? Realizadlo como prueba La asignación a una variable numérica. Podemos hacer: set /a i=14 set /a i=0x0E en ambos casos contendrá el decimal 14 (recordemos que el hexadecimal 0E equivale al decimal 14). Siempre los resultados nos los expresará en decimal. |. Al pulsar la tecla “intro”. set /a i=021 hay que tener cuidado con esto. Esto es válido realizarlo en un script. En ese momento se detendrá la ejecución del script y nos pedirá datos por pantalla. lo que hayamos tecleado se asignará a la variable de entorno definida en el set. una sintaxis del estilo: set /p variable=[literal] lo que hace es muestra el “literal” en pantalla y el cursor se queda a continuación esperando que metamos un dato. Es decir. por tanto. Y para finalizar el modificador /p. CARACTERES ESPECIALES Hay ciertos caracteres “especiales” que hay que usar con extremada precaución: por ejemplo. simplemente lo empezamos por cero. * Ya que hemos empezado con el comando “set” vamos a finalizar todo lo que dicho comando puede hacer. <. ejecuta lo que hay después del &. Esto puede ser útil para convertir directamente de hexadecimal o bien de octal a decimal de una manera rápida. caracteres reservados como &. si queremos introducir un numero en octal. si ejecutásemos: set var=a&a . puede ser decimal. hexadecimal u octal. ejecuta lo que hay antes del & “y” además a continuación. El carácter & (“and” en inglés. a no ser que lo necesitemos explícitamente. ya que el octal 021 es el decimal 17. Podéis comprobarlo en pantalla simplemente tecleando la línea anterior y viendo el resultado. Además de lo anterior: set p nos mostrará en pantalla “todas” las variables de entorno que empiecen por p. ^. Por ejemplo: set /p dato=Introduce datos: Nos mostrará por pantalla: Introduce datos:_ y cuando introduzcamos los datos los asignará a la variable “dato”. se los asignará a dicha variable y continuará la ejecución del script. >. %. Pero… ¿y si realmente queremos asignar el contenido del literal “a&a” a la variable “var”. el intérprete de comandos intenta ejecutar lo que hay después del &. En nuestro caso deberíamos haber hecho: set var=a^&a Si posteriormente ejecutamos un: echo %var% nos seguirá mostrando un error. programa o archivo por lotes ejecutable * ¿Qué ha hecho el sistema? Ha ejecutado el comando que hay antes del &. Si hacemos: set var=a^=b la variable “var” quedará con el contenido “a=b”. por tanto. Esto nos puede causar problemas posteriores si lo que queríamos hacer era asignar sólo “prueba”. NOTA: Un error bastante corriente cuando se usan caracteres de asignación y concatenación (&) en la misma línea puede ser: set var=prueba & set var1=otra_prueba ¿Cuál es. Como “a” no es un comando reconocido.com. Para ver que realmente tiene el contenido solicitado. o puede ser. la subcadena desde la posición “n” con longitud “m”. ni el nombre de otro script nos dará el error mostrado anteriormente. cómo lo hacemos? Simplemente anteponiendo el carácter ^ a cualquiera de los caracteres especiales. Por ejemplo. nos mostrará “a” e intentará ejecutar lo que va a continuación: intentará la ejecución de un comando llamado “a”.m% Esto nos extrae de la variable “var”. la primera posición es la 0. es decir “prueba “. A continuación.exe. Curiosamente: set var=a&cmd ¿qué hace? Ejecutadlo y ved el resultado. el contenido de var y otro *. Se puede comprobar si a continuación de lo anterior ejecutamos: set v 1) FUNCIONES SOBRE VARIABLES DE CARACTERES * Extraer una subcadena: %var:~n. las cuales mediante algún modificador especial en el comando set (/a) pueden tratarse como numéricas para realizar algunas pequeñas operaciones matemáticas. – OPERACIONES CON VARIABLES DE ENTORNO Hemos visto hasta el momento que las variables de entorno no son nada más que cadenas de caracteres. redirigir la salida a un archivo (los símbolos de redirección y su significado los veremos más adelante). por ejemplo un *: echo *%var%* Lo cual nos mostrará un *. Es decir: ¿qué hemos asignado a la variable “var”? podemos suponer que “prueba”.nos dará un error que veremos por pantalla: “a” no se reconoce como un comando interno o externo. ni un . con un espacio en blanco al final. Obtendríamos: *prueba * con el fatídico (en este caso) carácter en blanco al final. Igualmente veremos las llamadas variables dinámicas de entorno: variables que aunque no veamos mediante el comando “set” pueden usarse en instrucciones de comandos. “n” es el desplazamiento empezando a contar desde 0. Esto no es “del todo” verdad. es que la propia ayuda nos dice: “El comando SET no permitirá que un signo de igual sea parte de una variable”. O bien. podemos hacer dos cosas: set v el nos mostrará el contenido de todas las variables que empiezan por “v” y podremos comprobar que la variable “var” contiene lo que realmente deseábamos. un error que viene en la propia ayuda de Windows del comando set. hemos asignado todo lo anterior al &. es decir: set var=a Por tanto le ha asignado a la variable de entorno “var” el contenido “a”. es decir intenta interpretar el comando “a”. Podemos verificarlo tecleando entre algún delimitador. Vamos a ver primero las funciones que podemos aplicar a las variables de caracteres y en segundo lugar las operaciones matemáticas que podemos hacer así como su precisión cuando el contenido es numérico. el error cometido? pues…recordemos que todo lo anterior al & se ejecuta como un comando. Tengamos siempre presente que los caracteres “especiales” deben llevar el símbolo ^ precediéndolos. ya que aunque realmente tiene el contenido “a&a”. ni un . Pero no es así. la segunda . se refiere a *toda* la cadena menos “m” caracteres.operadores unarios * / % – operadores aritméticos .5% al no especificarse posición se asume desde el principio de la cadena y por tanto nos mostrará 5 caracteres iniciales. es decir “89″. un literal por otro: %var:str1=str2% Este comando buscará todas las ocurrencias de la subcadena “str1″ dentro de “var” cambiándolas por “str2″. se refiere a la longitud de toda la cadena menos ese número. NOTA1: puede omitirse “str2″. etc. hasta el *final* de la variable (ya que no se ha especificado longitud). Por ejemplo: set var=12345xx6 set var=%var:xx=% echo %var% NOTA2: se cambiarán todas las ocurrencias de “str1″. Pongamos un ejemplo: set var=123456789 echo %var:~1. veremos: “2345″.la 1. por ejemplo: %var:~1% nos mostrará desde la posición 2 (offset de 1). Igualmente la máxima precisión es 2^32. Por “expresión matemática” puede entenderse cualquiera de las siguientes y en orden de precedencia de mayor a menor (extraído de la propia ayuda del comando set): () – agrupar ! ~ – . Por ejemplo: set var=hola cómo estás Ejecutad para verlo: echo %var:cómo=que tal% Igualmente podríamos asignárselo de nuevo a “var” o bien a otra nueva variable de entorno. NOTA: si “n” es un número negativo. Es decir. set var=123456789 echo %var:~. mostrará en el ejemplo anterior: “23456789″. * Sustituir dentro de una cadena. Igualmente: %var:~. En ese caso la cadena str1 dentro de la variable var quedará eliminado. Igualmente. En general la sintaxis es: set /a var=expresión matemática.-2% nos mostrará todo menos los dos últimos caracteres de la cadena. Debemos primero hablar de la precisión: sólo se opera con números enteros. En nuestro caso “12345″. Por tanto. Por ejemplo: set var=123456789 echo %var:~-2% nos mostrará los dos últimos caracteres de la cadena. Si “str1″ figura varias veces se cambiará todas las veces en la cadena de caracteres. Tanto n como m. son opcionales. Es decir. 2) FUNCIONES MATEMÁTICAS SOBRE VARIABLES DE ENTORNO Con el modificador /a en el comando set podemos realizar operaciones matemáticas *simples* sobre variables. Por ejemplo: set var=%var:cómo=que tal% con lo cual el contenido habría quedado modificado.4% nos mostrará la subcadena de “var” que va desde la posición 2 (recordemos: con desplazamiento +1 ya que empieza por 0) y con longitud 4. Por tanto la división de 5/2 nos dará como contenido un 2. es decir “1234567″. si “m” es negativo. z=16 set /a z-=(x-y)/2+5^<^<2 Quizá no sea tan trivial el ver que el resultado de lo anterior es -16. el bit a bit exclusivo ^. <. por ejemplo: &. %ERRORLEVEL% – se expande al valor de NIVEL DE ERROR actual %CMDEXTVERSION% – se expande al número actual de versión de las extensiones del comando del procesador (lo veremos posteriormente) %CMDCMDLINE% – se expande a la línea de comando original que invocó el Procesador de comandos. Cada vez que ejecutemos: echo %TIME% nos dará dinámicamente la hora del sistema. es decir: set /a x+=1 (a la variable “x” sumarle 1 y asignárselo a “x”) Lo mismo: set /a x=x-1 es equivalente a: set /a x-=1 set /a x=x*23 es equivalente a: set /a x*=23 etc… para el resto de operaciones matemáticas de asignación citadas anteriormente. >.+ – . Veamos los matices de lo anterior. vamos a introducir el por qué algunas veces . Un ejemplo de esto es la variable %TIME%. será asumido que contiene un cero. z vale 3 3) VARIABLES DINÁMICAS DE ENTORNO Son variables que aunque no veamos mediante el comando “set” tienen contenido que va variando o puede variar dinámicamente. %TIME% – se expande a la hora actual usando el mismo formato que el comando TIME. |. debe escribirse como ^^ ya que si no el intérprete de comandos lo interpretará erróneamente. %RANDOM% – se expande a un número decimal aleatorio entre 0 y 32767. Es decir. Veamos ejemplos de “asignaciones”. y vale 7. set /a x=x+1 podemos sustituirlo (abreviarlo) por una notación similar al C o C++. %DATE% – se expande a la fecha actual usando el mismo formato que el comando DATE. TIP: Aunque no lo he encontrado documentado. Veamos el siguiente problema: ¿qué solución tiene? set /a x=8. o incluso ^. Cada uno de ellos debe ir precedido por un ^. PRECAUCIONES EN LA EXPANSIÓN DE VARIABLES DE ENTORNO Aunque lo veremos en detalle posteriormente. Intentad razonarlo. pueden hacerse operaciones del tipo: set /a x=(y=3+4)*(z=2+1) x vale 21.operadores aritméticos << >> – desplazamiento lógico (bit a bit) & – bit a bit y ^ – bit a bit exclusivo o | – bit a bit = *= /= %= += -= – asignación &= ^= |= <<= >>= . y=2. ya que si no tenemos en cuenta algunas matizaciones ya comentadas en este documento habrá expresiones que nos darán error. Estas variables son (auto-explicativas desde la ayuda del comando set): %CD% – se expande a la cadena del directorio actual. – separador de expresión Si usamos una variable de entorno dentro de una expresión matemática y dicha variable no existe. IMPORTANTE: Volvamos a recordar que hay símbolos especiales que no pueden escribirse directamente. aparecen las variables de entorno en un script encerradas entre símbolos “!” en vez de los clásicos “%” y cuándo debemos usar el símbolo “!”. ATENCIÓN: El intérprete de comandos lee una línea de ejecución completa y lo primero que hace es sustituir las variables de entorno antes de procesarla. Esta máxima debemos tenerla presente siempre. Veamos un ejemplo que, aunque aparentemente está bien escrito, nos producirá siempre resultados anómalos o no esperados: set var=antes if %var%==antes (set var=despues&if %var%==despues echo “Cambiado a despues”) Hemos introducido el comando “if”. Realmente un “if” no es nada más que un “si” condicional en castellano. Es decir: si se cumple una expresión, entonces se ejecuta lo que va a continuación. Si además ponemos la palabra reservada “else”, esto se ejecutará en caso contrario. Recordemos igualmente que los paréntesis tienen precedencia. Veamos entonces el conjunto de las instrucciones anteriores: asignamos “antes” a la variable “var”. En la segunda línea preguntamos: Si la variable “var” contiene “antes” -que sí que es verdad-, ejecutaremos: asignar a la variable “var” la palabra “despues” y además a continuación comprobar que si tiene el contenido de “despues” -lo cual parece que es evidente puesto que acabamos de hacerlo- sacaremos por pantalla el texto “Cambiado a despues”. Nos parece por tanto obvio que lo que vamos a ver después de ejecutar los comandos anteriores es “Cambiado a despues”. Pues bien, si lo hacemos…sorprendentemente veremos que no sale nada. ¿No lo cambia? Realmente lo cambia, porque si a continuación de lo anterior ejecutamos: echo %var% veremos que contiene “despues”. Entonces ¿por qué no ha ejecutado correctamente lo que tenemos después del & en la línea anterior? Volvamos a leer ahora despacio el párrafo que he comenzado anteriormente por “ATENCIÓN”. Repasemos lo que hace por defecto el intérprete de comandos: lee la línea *entera* y en ese momento el contenido de las variables de entorno queda sustituido por el contenido real. A continuación, ejecuta la línea entera. Es decir lo primero que hace el intérprete de comandos es la “expansión” de la línea, y por tanto, antes de ejecutarla, quedaría: if antes==antes (set var=despues&if antes==despues echo “Cambiado a despues”) es evidente…que el segundo IF no lo ejecutará nunca. Este es el funcionamiento por defecto del intérprete de comandos. Si queremos que no funcione así, y que haga dinámicamente la expansión de las variables (y no “antes” de ejecutar la línea de comando) hay que ejecutar dos cosas: 1) Arrancar el intérprete de comandos con el parámetro /V:ON para indicarle que debe expandir las variables. (Si estamos en un script, colocar como primera línea del script: setlocal ENABLEDELAYEDEXPANSION. Lo veremos más en detalle posteriormente) 2) Referenciar las variables que deben ser expandidas en ese momento, y no en el momento de leer la línea por primera vez mediante los símbolos de “!” en vez de “%”. En nuestro caso, y para verlo más claro: 1) En inicio-ejecutar arrancamos el intérprete de comandos como: cmd /V:ON 2) Ejecutamos: set var=antes if %var%==antes (set var=despues&if !var!==despues echo “Cambiado a despues”) Nótese el cambio de “%” por “!” en el segundo IF. En este caso podemos comprobar que la ejecución es lo que deseábamos. Volveremos con estos temas más adelante. ENTENDIENDO LA ENTRADA/SALIDA BÁSICA DE COMANDOS Cuando ejecutamos un comando en una consola puede ser de dos tipos: o bien un comando interno de la shell de comandos (cmd.exe) o bien un programa externo (.com, .exe, .bat, etc.). Lo primero que verifica el intérprete de comandos es si es un comando interno (por ejemplo “copy”). Si lo es, lo ejecuta directamente. Si no pertenece a su tabla interna de comandos, empieza su búsqueda: * ¿Dónde y cómo lo busca? 1) Si se ha tecleado extensión del comando, por ejemplo: “ping.exe” se buscará sólo con dicha extensión. Si no se ha tecleado extensión, es decir, simplemente es “ping”, lo primero que hace el sistema es localizar la variable de entorno %PATHEXT% para ver las posibles extensiones y su orden de búsqueda. En un entorno NT (y XP lo es), si ejecutamos: echo %PATHEXT% veremos su contenido: PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH Es decir, primero intentará localizar un ping.com, si lo encuentra lo ejecuta, si no lo encuentra buscará un ping.exe, si lo encuentra lo ejecuta, etc… 2) Hemos hablado de que intentará localizar los anteriores. Pero ¿dónde? 2.1) En primer lugar en el directorio en curso. 2.2) Si no lo localiza, buscará en la variable de entorno %PATH% e irá recorriendo carpeta por carpeta y dentro de cada una de ellas, si no se ha tecleado extensión, en el orden predeterminado de extensiones de la variable %PATHEXT% 2.3) Si al final de esta búsqueda lo encuentra, lo ejecutará. En otro caso nos enviará un mensaje de error como por ejemplo: C:\>micomando “micomando” no se reconoce como un comando interno o externo, programa o archivo por lotes ejecutable. *** Debemos fijarnos en que básicamente un comando es “algo” que puede solicitar datos de entrada, posteriormente hace “algo” y por último nos da datos de salida. Por ejemplo: copy c:\carpeta\archivo.dat d:\backup El comando (interno) copy, recibe datos, en este caso de la propia línea de comandos (y en la consola). Esos datos son dos: “c:\carpeta\archivo.dat” y “d:\backup”. A continuación ejecuta la copia. Y por último nos informa de cómo ha ido esa copia. Nos puede dar dos tipos de mensajes: a) O bien nos informa de copia correcta: ” 1 archivos copiados.” b) o puede informarnos de una situación de error, por ejemplo: “El sistema no puede hallar el archivo especificado.”, o bien: “Acceso denegado. 0 archivos copiados.” En general los programas o comandos tienen una entrada de datos estándar (STDIN), y una salida de datos cuando ocurre un funcionamiento correcto (STDOUT) y cuando ocurre algún tipo de error (STDERR). Fijémonos que las tres, en los casos de comando de consola, en general, están redirigidas a la propia consola. Tanto la entrada de datos como los mensajes, sean o no de error, “entran” y “salen” por pantalla. Pero… el comando o programa, internamente los redirige a salidas o entradas que pueden físicamente estar redirigidas, o ser redirigidas desde dispositivos que no sean la consola. Técnicamente, esto se hace a nivel del “handle” (manejador) del fichero. Algunas veces en la literatura hispana esto se ha mal traducido por controlador. Básicamente un “handle” es un simple número que referencia internamente en un programa a un fichero. Fijémonos que realmente la entrada de datos es “como” si estamos leyendo de un fichero y la salida es como si se “escribe” en un fichero, aunque en el ejemplo que acabamos de ver, estos ficheros son redirigidos a la propia consola. Existen tres números, o handles, que históricamente en informática han representado siempre lo mismo: el 0 (STDIN), el 1 (STDOUT) y el 2 (STDERR). El resto son libres, a voluntad del programador. Por tanto, y de cara interna a un programa, los datos que recibe de entrada se leen por STDIN, los mensajes de salida se escriben en STDOUT, y los mensajes de error en STDERR y además se activa un código de error (aunque algunas veces es costoso de distinguir, ya que sólo está en la cabeza del programador que lo haya realizado, qué es lo que él considera mensaje informativo y lo que considera mensaje de error… pero esto es otra cuestión). Debido a la estandarización del STDIN, STDOUT y STDERR (“handles” 0, 1 y 2) lo que normalmente hace un sistema operativo es redirigir estos a la consola. Este es el comportamiento estándar del sistema, pero nosotros podemos igualmente hacer que sean redirigidos a donde queramos, tal y como veremos posteriormente. Por ejemplo, en el caso del ejemplo anterior del comando “copy”, podemos hacer: copy c:\carpeta\archivo.dat d:\backup > c:\log.txt El símbolo “>” está indicando que todo lo que vaya a salir por el STDOUT se escribirá, en vez de en la consola, en un archivo de texto c:\log.txt. Repito, porque es importante el matiz: STDOUT a fichero de texto. Es decir, si el comando copy no puede copiar, recordemos que el mensaje de error lo saca en STDERR, por tanto en el fichero de texto no se escribiría nada, ya que en el ejemplo anterior, con el símbolo >, sólo se ha redirigido el STDOUT. El STDERR queda con los valores predeterminados por el sistema operativo: es decir, se escribe el mensaje de error en consola. *** Hemos comentado que a voluntad del programador de un comando o programa, este puede terminar correctamente o bien establecer un código de error al finalizar (escriba o no además un mensaje explicativo). El sistema operativo es el encargado de capturar esos códigos de error y los deja a nuestra disposición en una variable de entorno llamada %ERRORLEVEL% Podemos, por ejemplo, verificar cual es el comportamiento del comando “copy”. Para ello vamos a realizar el siguiente ejemplo creándonos una carpeta de trabajo llamada c:\tmp c: cd \ md tmp echo “texto de un fichero” > c:\tmp\fichero.txt Con esto nos hemos posicionado en c: (por si no lo estuviésemos), hemos ido a su carpeta raíz (cd \), y hemos creado una carpeta llamada tmp en donde estuviésemos posicionados en ese momento (md tmp) -md es abreviatura de “makedir”: crear directorio-. La última línea (echo) nos mostraría por pantalla “texto de un fichero”, es decir nos lo mostraría en el STDOUT. Pero con el símbolo “>” lo que hacemos es redirigir el STDOUT (la consola en este caso) a un fichero que en nuestro caso es: c:\tmp\fichero.txt. Si lo abrimos con el cuaderno de notas, veremos realmente el texto anterior. Vamos a copiarlo en otro. Ejecutamos por ejemplo: copy c:\tmp\fichero.txt c:\tmp\copia.txt Si a continuación de este comando ejecutamos: echo %ERRORLEVEL% veremos que el comando anterior nos informa que ha terminado con 0 (se considera normalmente 0 una finalización correcta). Vamos a provocar que el copy termine con error para ver cual es su comportamiento en este caso. Un método muy sencillo seria proteger contra escritura el fichero de salida y luego intentar escribir en él. Es decir: attrib c:\tmp\copia.txt +r (+r es “read only” -sólo lectura-) copy c:\tmp\fichero.txt c:\tmp\copia.txt Vemos que ahora en pantalla nos informa que “Acceso denegado”. Si a continuación ejecutamos: echo %ERRORLEVEL% veremos que el código de retorno es 1. NOTA: en general los mensajes de error deben buscarse en la documentación del programa o entonces el > nos escribiría todos los mensajes. lo anterior no ha sido más que un ejemplo para intentar introducir los “redirectores” del sistema operativo. si el copy enviase un mensaje de error (STDERR) esto no se vería en el fichero. Pero también hemos comentado que sólo redirige en STDOUT.txt c:\tmp\copia. en lugar de en la ventana del Símbolo del sistema. Pero en cambio si redirigimos la salida de errores: STDERR (“handle” numero 2) al STDOUT (“handle” numero 1) y luego escribimos. Veamos. Pero… recordemos que > escribe el STDOUT.txt >c:\log.txt c:\tmp\copia. Mal traducido por canalización o filtro (“pipe”) Hemos visto que con >& se escribe la salida de un controlador (“handle”) en otro. Este es de los más interesantes ya que permite pasar “toda” una salida de datos a un programa que espera “toda” una entrada de datos en flujo. Tenemos tres programas del sistema operativo “more” (más). OPERADORES DE REDIRECCIÓN > Escribe la salida del comando (normalmente STDOUT) en un fichero o un dispositivo (puede por tanto redirigirse a otro dispositivo. de funcionamiento correcto o erróneo en el fichero. El sistema operativo lo único que hace es situarnos el código de retorno en %ERRORLEVEL% y nosotros podremos tomar acciones en un script de comandos analizando dicha variable de entorno cuando nos interese controlar los códigos de terminación. si hacemos: copy c:\tmp\fichero. Es decir. por tanto. No todos los programas están preparados para admitir este tipo de redirección y debe leerse la documentación de cada uno de ellos al respecto.txt 2>&1 >c:\log. Un ejemplo de canalización y redirección: imaginemos que queremos en nuestro disco todos los . en ese caso todo quedaría reflejado en el archivo log.txt *** Operador de canalización (“|”) o “pipe”. Un dir /s nos muestra todos los archivos desde donde estemos posicionados incluyendo todos los archivos en subcarpetas. En los ejemplos anteriores hemos visto que la salida de un comando como el copy podemos escribirlo en un fichero con el símbolo >. “find” (buscar) y “sort” (ordenar) que admiten pipes y que nos pueden servir de ejemplo. Por tanto: copy c:\tmp\fichero.txt sólo los mensajes de funcionamiento correcto quedarían en c:\log.txt. no sólo a archivo). >& Escribe la salida de un controlador en la entrada de otro controlador (lo vemos posteriormente en detalle) <& Lee la entrada desde un controlador y la escribe en la salida de otro controlador.comando ya que son a voluntad del programador. Realmente el “more” no es nada más que un programa que admite como entrada toda la salida de otro comando y que lleva un contador de líneas para irnos mostrando en pantalla 24 líneas y luego esperar a que pulsemos una tecla. Ejecutemos por ejemplo: dir c:\ /s | more (cualquiera de los comandos anteriores puede abortarse con CTRL-C). Esto es un problema si lo que queremos es crear un log de ejecución de un script para poder ver posteriormente la ejecución: los mensajes de error precisamente los habríamos perdido. Podemos redirigir la salida de este comando al “more”. en lugar de leerla desde la consola. >> Añade la salida del comando al final de un archivo sin eliminar la información que ya está en él. | Lee la salida de un comando y la escribe en la entrada de otro comando. Si ejecutamos: dir c:\ /s veremos que empiezan a pasar pantallas de datos que no somos capaces de leer. Vayamos a un ejemplo práctico. < Lee la entrada (STDIN) del comando desde un archivo. Bien. Si fuésemos capaces de “redirigir” el STDERR al STDOUT. txt Los parámetros que he puesto. con comandos de redirección para leer entradas y escribir salidas en archivos. incluso a un programador avezado le pueden causar más de un problema o costarle su correcta interpretación. CONFIGURACIÓN CÓMODA DEL INTÉRPRETE DE COMANDOS Aunque esto no tiene nada que ver con los scripts. esta es la acción “copiar” a la que estamos acostumbrados.txt.archivos con extensión . En ejemplos que iremos viendo a lo largo de estos capítulos quedará más claro el concepto. es simplemente botón derecho (sin haber marcado nada previamente). Una vez marcado. De esta manera. en función de resultados que vayamos obteniendo se pueden tomar acciones.. dentro del propio script.bat o .txt > listaalf. podemos fijarnos en que al abrir un intérprete de comandos (cmd. También pueden usarse. como cualquier programa. La acción “pegar”. La manera de configurar el intérprete de comandos es pinchando con el ratón en la esquina superior izquierda del intérprete de comandos. si usamos || sólo se ejecutará si la terminación de la instrucción previa termina incorrectamente (código distinto de cero) Por ejemplo: md kkk && echo “finalizado correcta la creación” Sólo veremos el mensaje de aviso si la creación de la carpeta kkk ha sido posible. CONCEPTOS EN UN SCRIPT – CONTROL DE FLUJOS Acabamos de ver unos conceptos sobre entorno.txt Esto indicaría que la entrada al comando sort viene redirigida desde el fichero lista. Por contra.log” > c:\ficheros_log. dir c:\ /b /s | find /I “. no es nada más que escribir en un archivo de texto con extensión . Otro ejemplo: ver en orden “inverso” los ficheros de un directorio: dir /b | sort /REVERSE Los filtros (“pipes”) no sólo admiten canalización. tanto en el comando dir. variables. etc. siempre podemos verlos ejecutando dir /? y find /? para buscar los que mejor se adapten a lo que queremos. como en el comando find. Lo que tengamos en el portapapeles (lo hayamos llevado mediante la acción anterior. imaginemos que tenemos un fichero con nombres y queremos ordenarlo alfabéticamente. propiedades. nos la escriba en listaalf. Recordemos algunas de las instrucciones vistas hasta el momento: . OPERADORES CONDICIONALES Son los operadores && y el operador || Lo que exista después del operador && se ejecutará “sólo” si la instrucción previa a él -en la misma línea. Por ejemplo.txt y que la salida. Simplemente: sort < lista. comandos. Además. ni tampoco hemos visto cómo el shell ejecuta el script y cómo se puede tener control sobre la ejecución. que son básicos para poder realizar un script. tal y como hemos comentado. o bien lo hayamos copiado desde cualquier otra ventana Windows) lo pegará en donde esté el cursor.log y dejar la información en un fichero de salida. con el botón izquierdo del ratón ya podremos marcar textos. *** Los símbolos de redirección y canalización son potentísimos y a veces. lo cual puede sernos incómodo en Windows. marcamos el casillero de “modalidad de edición rápida”. en vez de dejarla en pantalla. pinchamos botón derecho del ratón y esto nos lo envía al portapapeles (es decir.cmd todas las instrucciones que iríamos haciendo manualmente.ha terminado correctamente (código 0).exe) no se pueden realizar funciones de copiar y pegar. Básicamente un script de comandos. pero hasta el momento no hemos visto ninguna instrucción excepto las puestas en los ejemplos previos. etc… de acuerdo a las reglas vistas anteriormente). o un . Si queremos suprimir la salida de las líneas y dejar solamente la salida de los comandos. lo primero que hace es sustituir dicha variable por su contenido.cmd en mi usuario y en una nueva carpeta de pruebas llamada “tmp” con el contenido: set var=Hola echo %var% mundo.Instrucción: ECHO. Es decir. por tanto buscaría en la carpeta en curso y posteriormente en el PATH un programa (otro script. set var= Lo guardamos en disco y ahora lo ejecutamos. Es importante la matización anterior ya que la expansión de variables es el primer paso y lo es para todas las instrucciones. Nos creamos un script llamado por ejemplo: pr. su objetivo es mostrar por el STDOUT (normalmente la consola) el literal que exista a continuación. es decir “Hola mundo”. (un “.exe. Veamos su uso.” pegado a la instrucción sin separación: escribe una línea en blanco) ECHO ON ECHO OFF Estas dos últimas son instrucciones a ejecutar sólo dentro de un script. Es decir. lo primero que debemos decirle al script es que no queremos “ECO” de lo que va traduciendo. el intérprete de comandos: 1) Realiza la sustitución de las variables de entorno. si escribimos en un script: echo esto es %var% prueba y la variable de entorno “var” contiene el literal “una”. “ECHA” no es el nombre de un comando interno. por tanto la línea quedaría como: ECHO esto es una prueba 2) A continuación. en nuestro caso. En este caso podemos poner como primera línea del script: @ECHO OFF El símbolo @ como primer carácter en una línea del script indica que no queremos que esa línea se “vea” en la ejecución.com. o un . nos mostrará el literal “esto es una prueba”. Si lo encuentra ejecutará el programa o script “ECHA” y si no lo encuentra nos dirá que sucede un error. si existe una variable de entorno (delimitada por símbolos %). pero. no muestre nada de la ejecución (sí de la salida de instrucciones) por pantalla. cuando lo tenemos finalizado y correcto. o bien hasta que se encuentre otra orden ECHO ON. Si además le damos la orden ECHO OFF. lo lógico es ver sólo la salida y no línea por línea. nos quedan . ejecuta la instrucción: Como ECHO es un comando interno que escribe en el STDOUT lo que hay a continuación. le estamos diciendo que hasta el final del script. nos ha ido mostrando todas las líneas que va ejecutando y mezclado con las salidas que a su vez va dando el script. si no queremos ver nada más que el literal “Hola mundo”. Este “ECO” es útil cuando estamos depurando y probando un script. es decir. NOTA: La sintaxis completa de ECHO es: ECHO literal a escribir ECHO. ¿Qué vemos?: C:\Documents and Settings\miusuario\tmp>set var=Hola C:\Documents and Settings\miusuario\tmp>echo Hola mundo Hola mundo C:\Documents and Settings\miusuario\tmp>set var= Es decir. Si hubiésemos cometido un error y hubiésemos puesto: ECHA esto es %var% prueba 1) Expandiría la instrucción como: ECHA esta es una prueba 2) Intentaría ejecutar la instrucción. Recordemos que lo primero que hace el intérprete de comandos es “expandir” las instrucciones. NUL dispositivo nulo. hemos copiado desde la consola a un fichero de la misma forma que si hubiésemos copiado un fichero a otro fichero. vamos a ver las instrucciones de control flujo. Normalmente se usa después de una pregunta lógica por algún resultado (por ejemplo.txt. NOTA: Existe una etiqueta implícita en cualquier script que no es necesario definir. tiene un valor determinado. copiar la clave desde el mail recibido y guardar el fichero en la carpeta que queremos con el nombre licencia.txt fichero2. Lo que se envíe a él se escribirá en la impresora (si está asignada a ese puerto). 2) Queremos enviar un fichero a impresora: copy fichero. de nuestra máquina. La manera clásica de hacerlo mediante Windows es abrir el cuaderno de notas. copy fichero1. GOTO nombre_etiqueta Y en algún lugar de nuestro script debemos tener :nombre_etiqueta (nótense los “:”) En este caso.dos posibilidades: 1) Poner una @ al comienzo de cada instrucción en el script. podríamos hacer en una consola de comandos: copy con licencia. Bien. se pierde. normalmente lógicos. :EOF (End Of File – Fin de fichero). Veamos unos ejemplos: 1) Imaginemos que hemos recibido una clave de registro de un producto por mail. dentro de una instrucción IF). Lo que se envíe a él. O bien: 2) Poner como primera línea del script @ECHO OFF Vamos a hacer un paréntesis en este capítulo e introducir el concepto de nombre lógico de dispositivo.txt En este punto se quedará el cursor esperando una entrada. que indica el código de retorno de un comando anterior. Por tanto. Recordemos que lo encerrado entre corchetes es opcional if [not] errorlevel número comando [else expresión] Estamos verificando si la variable %ERRORLEVEL%. 1) Instrucción GOTO (ir a) Permite en un punto determinado de nuestro script “saltar” a otro punto del script. Lo que se envíe o reciba desde la consola se puede referenciar con CON.txt lpt1 3) No queremos ver. y para finalizar la entrada de datos le damos a CTRL-Z (CTRL-Z es la marca estándar de fin de fichero). Si lo tiene ejecutará el “comando” y si no lo . la ejecución de la instrucción GOTO :EOF implica que se saltará hasta el final del fichero y por tanto finalizará el script. buscará en el script la línea :nombre_etiqueta y bifurcará a dicha línea. Por ejemplo: CON se refiere a la consola. LPT1 se refiere a la impresora. al ejecutar la instrucción GOTO. llegado este punto sólo vamos a ver estos tres. por ejemplo después de un comando copy la línea de “xx archivos copiados” que siempre nos informa el copy. 2) Instrucción IF (si). Básicamente son 3.txt >nul RETOMANDO EL CONTROL DE FLUJOS DE EJECUCIÓN Una vez hecho el paréntesis anterior. Aunque existen más dispositivos lógicos. Simplemente redirigimos la salida al dispositivo nulo. Es decir. y lo queremos guardar en un fichero llamado licencia.txt en una carpeta determinada. Tecleamos la clave recibida (o la copiamos desde el mail). NOMBRES LÓGICOS DE DISPOSITIVOS Hay ciertos dispositivos que podemos usar en cualquier comando o dentro de un script con nombres reservados que se refieren a dispositivos. Se considera parámetro cualquier literal enviado en la línea que invoca al script. Hay que tener muchísimo cuidado con esto y no me gustan las instrucciones del estilo anterior a menos que tengamos delimitadores específicos. En la siguiente tabla puede ver los valores de operadorDeComparación. Cada parámetro se referencia dentro del script por %1. el truco consiste en encerrarlas entre algún delimitador. Es decir: if “%var1%”==”%var2%” echo “valen lo mismo” Esto al expandirse quedaría: if “hola mundo”==”2″ echo “valen lo mismo” La comparación se realiza entre literales entrecomillados lo cual no provoca error ni aun en el caso de que alguno sea nulo al no tener contenido. el nombre de un fichero y el nombre de una carpeta. Lo mismo pasaría si “var1″ o “var2″ no tienen contenido. sino que por primera vez se ha puesto “operadorDeComparacion”. sería: . al no ser iguales. if [not] exist nombreDeArchivo comando [else expresión] if [/i] cadena1 operadorDeComparación cadena2 comando [else expresión] El /i realiza la comparación de tal manera que no se distingue entre mayúsculas y minúsculas. llamémosle copia. la instrucción anterior. comillas -ya que estas definen un literal. Imaginemos que tenemos una variable “var1″ con contenido “1″ y otra “var2″ con contenido también “1″. %2. EQU igual a (es lo mismo que ==) NEQ no es igual a LSS menor que LEQ menor que o igual a GTR mayor que GEQ mayor que o igual a PARÁMETROS Cualquier script es capaz de recibir parámetros desde la línea invocante. if defined variable comando [else expresión] OPERADORES DE COMPARACIÓN Especifica un operador de comparación de tres letras. Este operador que veremos a continuación.”. Voy a intentar explicarlo. Pero… ¿y si “var1″ contiene “Hola mundo”. Al expandir la expresión quedaría: if Hola mundo==2 echo “valen lo mismo” Detrás del hola no hay símbolo de comparación. ejecutará precisamente ese ELSE. por lo cual la instrucción es sintácticamente incorrecta. siempre y cuando no exista ya en el destino.cmd. Fijémonos que hemos puesto no un == (igualdad) en este caos. y el símbolo == no es nada más que uno de ellos. En estos casos. Si “var2″ contiene un “2″. El objetivo del script es copiar el archivo desde la carpeta en donde estemos posicionados en la carpeta destino. sin verificar que los parámetros son correctos. Una manera grosera de realizar el script. La instrucción: if %var1%==%var2% echo “valen lo mismo” Se ejecutará sin problemas y nos sacará el mensaje “valen lo mismo”. etc… Vamos a crear un script que reciba dos parámetros. no mostrará nada. que sucedería? Pues un desastre.tuviese y hemos codificado en la línea (es opcional) un ELSE (en otro caso). Recordemos que lo primero que se hace es la expansión de variables. %3. if [not] cadena1==cadena2 comando [else expresión] cadena1 y cadena2 pueden ser cualquier cosa incluidas variables de entorno. Por ejemplo. El sistema considera que los parámetros están separados por espacios en blanco o bien por el delimitador “. Es decir “HOLA” es lo mismo que “hOLa”. Realmente para realizar correctamente el script deberíamos hacer: @echo off if {%1}=={} goto error if {%2}=={} goto error if {%3} NEQ {} goto error if not exist %1 goto error1 if not exist %2\nul goto error2 if exist %2\%1 goto aviso copy %1 %2\%1 2>&1 >nul if not errorlevel 1 goto correcto echo Copia errónea.xxx” “c:\carpeta destino” Nótese que hemos entrecomillado cada uno de los parámetros. realizaría: if not exist c:\backup\mifichero. goto :EOF :error1 echo Nombre del fichero origen no existe. Deben recibirse dos parámetros. goto :EOF :aviso: echo El archivo ya existe en el destino. tal y como está. goto :EOF :error2 echo Carpeta destino no existe.@echo off if not exist %2\%1 copy %2 %1 Si invocásemos al script de la siguiente manera: copia. * Verificamos que hemos recibido 2 parámetros y sólo 2.cmd mifichero. He comentado que este script. No se ha realizado copia. Si el nombre del archivo o el nombre de la carpeta destino tuviese espacios en blanco el sistema consideraría que dicho espacio en blanco es un delimitador de parámetros y por tanto nos llegarían al script más parámetros de los deseados. De esta manera sólo se recibirán dos parámetros ya que si no. Redirigimos todo a nul para que no de mensajes de archivos copiados.txt copy mifichero.txt c:\backup al desarrollar la instrucción el script. Para verificarlo usamos un pequeño truco: preguntar por el dispositivo “nul” en la carpeta destino. goto:EOF :error echo parámetros erróneos.cmd “nombre fichero. * Realizamos la copia. Verifique permisos de la carpeta destino. Comentemos un poco el script. Si no existe. es que la carpeta no existe. está realizado de una manera grosera. goto :EOF :correcto echo Archivo copiado correctamente. . goto :EOF Y la manera de invocar al comando sería: copia.txt c:\backup lo cual es precisamente lo que queríamos hacer. * Verificamos que exista el fichero origen * Verificamos que exista la carpeta destino. se recibirían 4 al usar como delimitador el sistema los espacios en blanco entre ellos. * Verificamos que de acuerdo a las especificaciones del script no exista ya el fichero en la carpeta destino. * Comprobamos el código de retorno y si no es cero enviamos el mensaje correspondiente. * Damos un mensaje de copia correcta cuando se ha finalizado correctamente el script. el cual tiene por objeto desplazar los parámetros.cmd 1 2 3 4 5 6 7 8 9 10 11 . Bien. El parámetro recibido en %0 no se teclea y siempre el sistema nos pasa como contenido el nombre del script invocado. Vamos a ver toda la casuística más en detalle. por ejemplo) de la siguiente manera: parm. Si pasásemos más. Es decir. etc… De tal manera que al final el %9 pasa a contener el posible décimo parámetro pasado. el ejemplo anterior nos puede servir para la introducción de lo que son los parámetros y cómo se deben usar o referenciar en el script. hay que usar el comando shift. el %3 pasa a ser el %2. al ejecutar shift lo que se hace es que el %2 pasa a ser %1 (el %1 se pierde por lo que debemos guardarlo). Realicemos como prueba: @echo off echo Antes de desplazar echo Parametro 1: %1 echo Parametro 2: %2 echo Parametro 3: %3 echo Parametro 4: %4 echo Parametro 5: %5 echo Parametro 6: %6 echo Parametro 7: %7 echo Parametro 8: %8 echo Parametro 9: %9 shift echo Despues de desplazar echo Parametro 1: %1 echo Parametro 2: %2 echo Parametro 3: %3 echo Parametro 4: %4 echo Parametro 5: %5 echo Parametro 6: %6 echo Parametro 7: %7 echo Parametro 8: %8 echo Parametro 9: %9 shift echo Despues de desplazar de nuevo echo Parametro 1: %1 echo Parametro 2: %2 echo Parametro 3: %3 echo Parametro 4: %4 echo Parametro 5: %5 echo Parametro 6: %6 echo Parametro 7: %7 echo Parametro 8: %8 echo Parametro 9: %9 e invoquemos al script anterior (parm.cmd. Realmente pueden pasarse más de 9 parámetros pero sólo 9 de ellos serán accesibles directamente. Hagamos una prueba: @echo off echo Parámetro 0: %0 %1 a %9 son los posibles parámetros enviados en la línea de comandos. Realmente podemos referenciar los parámetros desde %0 a %9. %~dp$PATH:1 Busca los directorios enumerados en la variable de entorno PATH para %1 y expande a la letra de unidad y ruta de acceso del primer directorio encontrado. %~d1 Expande %1 a una letra de unidad. No se pueden buscar y reemplazar valores ni examinar subcadenas. NOTA: En los ejemplos anteriores. Realmente todos los modificadores posibles de parámetros son los que se describen a continuación: %~1 Expande %1 y quita todas las comillas (“”).cmd 1 2 3 4 5 6 7 8 9 10 podemos comprobar la salida.cmd aaa.cmd): @echo off echo Parámetro 1 expandido: %~f1 echo Parámetro 2 expandido: %~f2 Supongamos que nuestro script esté en la carpeta: C:\Documents and Settings\miusuario\tmp> Al ejecutar: parm. Esto puede ser útil si luego queremos tratar todo como una sola línea y usamos comandos específicos. ruta y archivo en donde se esté ejecutando el script. A los parámetros y sólo a los parámetros.www bbb nos devolverá: Parámetro 1 expandido: C:\Documents and Settings\miusuario\tmp\aaa. Sin embargo. %~n1 Expande %1 a un nombre de archivo. para tratar dicha línea. %~p1 Expande %1 a una ruta de acceso. %~a1 Expande %1 a atributos de archivo. No se pueden manipular parámetros de proceso en los scripts de la misma manera en que se manipulan variables de entorno (funciones de manejo de cadenas vistas anteriormente). Vamos a ver un ejemplo y a continuación daremos todas las posibilidades. se puede reemplazar %1 y PATH con otros valores de parámetros de proceso por lotes. %~f1 Expande %1 y lo convierte en un nombre de ruta de acceso completo. La tabla siguiente enumera las combinaciones posibles de modificadores y calificadores que puede usar para obtener resultados compuestos. Si el nombre de la variable de entorno no está definido o la búsqueda no encuentra el archivo. el delimitador %~f por delante del numero de parámetro nos expande el parámetro considerándolo como si fuese nombre de archivo (sin verificarlo) al nombre completo de unidad. %~x1 Expande %1 a una extensión de archivo. %~$PATH:1 Busca los directorios enumerados en la variable de entorno PATH y expande %1 al nombre completo del primer directorio encontrado. este modificador se expande a la cadena vacía. %~dp1 Expande %1 a una letra de unidad y una ruta de acceso. que veremos más adelante. %~ftza1 Expande %1 a una línea de salida similar a dir. %~z1 Expande %1 a un tamaño de archivo. %~t1 Expande %1 a una fecha/hora de archivo.NOTA: Podemos referenciar “toda” la línea de parámetros mediante %* Si reescribimos el bat anterior: @echo off echo Toda la línea de parámetros es: %* y ejecutamos parm.www Parámetro 2 expandido: C:\Documents and Settings\miusuario\tmp\bbb Es decir. Hagamos un script (parm. se puede asignar el . %~nx1 Expande %1 a un nombre y extensión de archivo. %~s1 Ruta de acceso expandida que únicamente contiene nombres cortos. pueden anteponérseles modificadores los cuales realizan una conversión especifica. * Llamada a procedimiento interno (subrutina). es decir la línea: CALL invocado.cmd sólo tuviese: invocado. manipular la variable de entorno.cmd: @echo off echo estoy en el principal echo mi primer parámetro: %1 echo mi segundo parámetro: %2 call invocado. Pongamos un ejemplo (script. Se considera la finalización de la subrutina cuando se alcanza el fin del archivo por lotes. ya que algunas veces nos puede ser necesario usarlos para expansión sobre todo en nombres de archivos.cmd y con el contenido: @echo off echo estoy en el principal call invocado. INVOCACIÓN A PROCEDIMIENTOS. Pero cuando este terminase. El primero de ellos lo llamaremos principal. hubiésemos omitido dicho CALL. La sintaxis es “CALL :nombre”.cmd: @echo off echo estoy en el invocado Si lo ejecutamos veremos los resultados. pero a diferencia del goto. después. o llamar a una subrutina del mismo procedimiento.cmd también se ejecutaría el invocado. que el ejemplo anterior.cmd) @echo off echo Parámetro 1: %1 echo Parámetro 2: %2 call :rutina1 %2 echo estoy de nuevo en el principal call :rutina1 %1 echo estoy de nuevo en el principal call :rutina2 parametrosjuntos%1%2 . * Llamada a procedimiento externo. INSTRUCCIÓN CALL Muchas veces es necesario desde un script llamar a otro procedimiento. cuando finalice la propia rutina continuará la ejecución después del CALL invocante. Aunque no es necesario memorizarlos sí que es importe saber que existen. Recordemos que tanto el procedimiento principal como el invocado pueden recibir parámetros y podemos jugar con ellos como queramos.cmd echo de vuelta en el principal Y un segundo procedimiento llamado invocado.cmd: @echo off echo estoy en el invocado echo el parámetro del invocado es: %1 y ahora lo ejecutamos como principal. Vemos ambos casos. en donde :nombre es un nombre de etiqueta interno al cual saltará la ejecución del script.parámetro a una variable de entorno para.cmd %2 echo de vuelta en el principal invocado. si en vez de llamar con CALL.cmd primero segundo ¿Qué es lo que vemos?… Nótese. Vamos a crearnos dos script. terminaría todo y no volvería al script principal. Por ejemplo: principal. Por tanto. y además que el script limpiase sus variables internas antes de finalizar. Si un script llama a otro script (mediante CALL) tendrá acceso a todas las variables modificadas en el script principal. esto *sólo* afecta a dicho programa (y por supuesto a los que él invoque. Esto es válido y hemos usado una variable llamada “computername” simplemente porque se nos ha ocurrido en el script. ya que heredarán su entorno). y lo ideal sería que el script. lo que sucede es que al finalizar el script.exe (aunque sea el invocante del script). No es conveniente modificar el entorno del cmd. con lo que provoca la condición de vuelta que hemos citado anteriormente).exe que lo ha invocado. Pero ¿cuál es el entorno de un script? Un script no es en sí un programa: es una secuencia de comandos dentro del shell. y además con otra variable “a” que antes de empezar el script no tenía valor. Un script no tiene entorno propio: se usa. Dentro del cmd. curiosamente. le estamos diciendo desde la instrucción “setlocal” que todo lo que hagamos será local al script.exe invocante (y sólo a él.exe -y sólo esese quedará en su entorno con una variable que ya existía modificada por el script. y por tanto se modifica o se añaden variables al entorno del cmd. si en el script anterior hubiésemos hecho: @echo off setlocal set a=%1 set computername=%a%_mio …… endlocal Es decir. si se modifican o añaden variables de entorno. este último no se verá afectado). Pongamos un ejemplo: un simple script que haga: @echo off set a=%1 set computername=%a%_mio …. Y cuando se ejecuta “endlocal” (al final del script) le estamos diciendo que deshaga todas las variables usadas y permanezca tal y como estaba desde que se ejecutó la anterior instrucción “setlocal”.exe. La instrucción “setlocal” admite además opcionalmente la siguiente sintaxis: . Esto es engorroso y normalmente difícil de controlar. Pero. Pero además dentro “sólo” del cmd. ese cmd.exe. dejase el entorno tal y como estaba antes de arrancarse. es decir si tenemos arrancado o arrancamos posteriormente otro cmd. al finalizar. ese nombre de variable ya existía en el sistema (en el entorno del cmd.esto dependerá de la lógica-) el usar un “setlocal” al inicio del script y un “endlocal” como última instrucción del script. Por ejemplo. Lo ideal sería no usar nombres que ya existan en el entorno en el propio script. y que por tanto.exe). El sistema nos da la posibilidad de hacerlo él automáticamente mediante las instrucciones “setlocal” y “endlocal”. CONSIDERACIONES SOBRE ÁMBITO DE VARIABLES Hemos comentado anteriormente que cada programa tiene su área de entorno la cual es una copia del área de entorno del programa invocante. Como norma es conveniente en los scripts (o al menos en el principal si usásemos llamadas CALL . Esto indica que cuando se la invoca con CALL volverá a la línea de continuación del invocante (realmente salta a fin de fichero.goto final :rutina1 echo en la rutina recibo parámetro: %1 goto:EOF :final echo estoy ya al final Fijémonos que la subrutina la terminamos con goto :EOF. excepto para el comando más potente de Windows: el comando FOR. y por ello hay que prestar especial atención a la expansión de las variables de entorno en la línea de comando antes de que esta pase a ejecución (recordemos la sintaxis con “!” como delimitador de la variable de entorno en vez de usar el delimitador “%” normal.chm que reside en \windows\help.ya las hemos comentado: por defecto el intérprete de comandos tiene desactivada la expansión diferida (a menos que se haya arrancado con /V:ON o bien se hayan modificado ciertas claves de registro para cambiar el comportamiento general del intérprete de comandos). Podemos ver estas modificaciones pidiendo la ayuda de cualquiera de las instrucciones anteriores. Las dos primeras: {enableextension | disableextensions} no es conveniente tocarlas ya que se desactivarían las extensiones de comandos y las instrucciones: DEL o ERASE COLOR CD o CHDIR MD o MKDIR PROMPT PUSHD PUSHD POPD SET SETLOCAL ENDLOCAL IF FOR CALL SHIFT GOTO START (también incluye cambios en la invocación de comandos externos) ASSOC FTYPE Tendría un comportamiento diferente. tal y como viene Windows. por tanto. Recordemos igualmente que hay una lista alfabética y detallada en el fichero de ayuda ntcmds. es conveniente siempre poner al comienzo del script principal la instrucción: setlocal enableextension enabledelayedexpansion con lo cual ya podremos usar el delimitador “!” cuando nos interese. por ejemplo CALL /? Por defecto.setlocal {enableextension | disableextensions} {enabledelayedexpansion | disabledelayedexpansion} Algunas de ellas -las dos últimas. el valor es: setlocal enableextension disabledelayedexpansion Debido a que es posible que el sistema en donde se vayan a ejecutar nuestros scripts pueda haberse modificado el comportamiento global. Vamos a dar un repaso de todas formas y un pequeño comentario a cada uno de ellos. Mi consejo además es permitir la expansión diferida del entorno. Es conveniente para los que se vayan a dedicar a la escritura de scripts el tener un acceso directo en Windows a dicho archivo. En esa lista alfabética figuran tanto los comandos internos de Windows como los externos que nos da la propia versión del sistema operativo. el cual . COMANDOS INTERNOS DEL INTÉRPRETE DE COMANDOS Llegado a este punto ya podemos ver todos los comandos internos que tiene el intérprete de comandos. siempre es conveniente forzar en nuestro script principal lo que deseamos. Es conveniente revisar ese capítulo ya que el concepto es extremadamente importante). Definición: Ejecuta un comando especificado para cada archivo de un conjunto de archivos. Los comandos internos son: ASSOC Ver / cambiar asociación a la extensión de un archivo.merecerá todo un capítulo aparte. Los subíndices del comando -tal y como se verán a continuación. SHIFT Desplazamiento de los parámetros con que se invoca a un script. COPY Copiar archivos. Por tanto. CD o CHDIR Cambiar carpeta en curso. PUSHD Guarda el nombre del directorio actual para que lo use el comando POPD. Utilice %%variable para ejecutar el comando for dentro de un archivo por . pero en un script deben expresarse con un doble símbolo. ENDLOCAL Fin de tratamiento de variables locales de entorno.exe. EXIT Final de la secuencia de comandos por lotes o sale de un cmd. FOR (lo veremos en todo un capítulo aparte). RM o RMDIR Borrar una carpeta. ECHO Mostrar por pantalla (en STDOUT). (Salto incondicional a una etiqueta del script en curso). DIR Listar contenido de la carpeta en curso. FTYPE Muestra o modifica los tipos de archivos empleados en asociaciones de extensiones de archivo. COMANDO ‘FOR’ Es el comando más importante y más potente que podemos usar en un script. CLS Borrar pantalla.exe si se invoca directamente. START Inicia una ventana independiente de símbolo del sistema para ejecutar un programa o un comando especificado. NOTA: Es el único comando que tiene sintaxis diferente ejecutado desde la línea de comandos y ejecutado desde un script. REN o RENAME Renombra un archivo o una carpeta. POPD Cambia el directorio actual al que se haya almacenado con PUSHD. CALL Llamada a procedimiento. COLOR Atributos de color en el texto enviado a consola. DEL o ERASE Borrar archivos. GOTO Ir a. SET Asignación de contenido a variables de entorno. vamos a verlo en detalle y haciendo hincapié en ejemplos de su uso. Representa un parámetro reemplazable. TYPE Vuelca el contenido de un archivo al STDOUT.se expresan con un símbolo % desde la línea de comandos. VER Muestra el número de versión de Windows. SETLOCAL Tratamiento o comportamiento de las variables en un script y de las extensiones de comandos. REM Es un comentario en un script.chm. Es conveniente llegado a este punto que se vaya consultando cada uno de los comandos que citaré a continuación en ntcmds. Admite varias formas: (recordando que en script %variable debe ser %%variable) 1) for %variable in (grupo) do comando %variable Requerido. Sintaxis. IF Instrucción de comparación. es decir con %%. Utilice %variable para ejecutar for en el símbolo del sistema. MD o MKDIR Crear una carpeta. PROMPT Cambia el símbolo de sistema de Cmd. Lo que va a continuación no se ejecuta. PAUSE Detiene la ejecución de un script y espera a que se pulse una tecla para continuar. PATH Como instrucción devuelve el contenido de la variable %PATH%. intervalo de valores o cadena de texto incluido en el (grupo) especificado.rpt) (ar??1991. %B o %C.txt *. El parámetro grupo puede representar un único grupo de archivos o varios.exe en Windows) -ver capítulos anteriores.*) do @echo %f Pero esto no es lo que se solicita. intervalo de valores o cadenas de texto que se desea procesar con el comando especificado. sino que. La sintaxis es: for /D %variable in (grupo) do comando [opcionesDeLíneaDeComandos] Por ejemplo.*) do @echo %s 3) for /R [unidad :]rutaDeAcceso] %variable in (grupo) do comando . para recorrer todas las subcarpetas de la carpeta Windows: for /d %s in (c:\windows\*.*) do @echo %%f nos mostrará los archivos que están dentro de la carpeta c:\windows (similar a un “dir” pero sólo nos mostrará el nombre.doc) (*..* ap??1991. Especifica uno o varios archivos. (grupo) Requerido. * y ?) para especificar un grupo de archivos.me) (ene*. (la respuesta a estos ejercicios al final del capítulo). Puede utilizar caracteres comodín (es decir.es posible también las sintaxis que veremos a continuación 2) for /D %variable in (grupo) do comando /D -> Sólo directorios Si grupo contiene caracteres comodín (* y ?).doc feb*.ccc.xxx. y lo que queremos es únicamente el nombre y extensión del archivo. directorio.lotes. como %A. etc. NOTA: Hay que prestar especial atención al posible uso del %variable dentro de la acción ‘do’ así como al posible uso de variables dentro de él. Las variables distinguen entre mayúsculas y minúsculas y se deben representar con un valor alfabético. se obtenga el mismo resultado que con las tres instrucciones anteriores. Si lo ejecutamos vemos que la salida es c:\windows\fichero.*) por ejemplo.doc *. Recordemos la parte vista anteriormente de expansión diferida o no del comando a la hora de traducir la línea. con una sola línea for y sin estar posicionado en la carpeta de Windows. Los siguientes son grupos de archivos válidos: (*. Especifica el comando que desea ejecutar en cada archivo.rpt feb*.doc ene*. Evidentemente una manera simple de hacerlo sería: c: cd \windows for %f int (*. el comando especificado se ejecuta para cada directorio (en lugar de un grupo de archivos de un directorio especificado) que coincida con grupo. c:\windows\fichero2. desde la línea de comandos: for %f in (c:\windows\*. Ejercicio [for-1]: usando el comando for en la forma citada anteriormente obtener únicamente el nombre del archivo.*) do @echo %f o bien desde un script: for %%f in (c:\windows\*. Los paréntesis son obligatorios. comando Requerido. NOTA: Cuando están habilitadas las extensiones de comandos (es el valor por defecto del cmd. directorios. ) do ( set ruta=%%a&@for %%f in (“!ruta:\. un delimitador como puede ser “. Es la parte más potente del FOR ya que permite ejecución interna de comandos dentro del propio “do” -realiza o puede realizar “spawn” del posible comando dentro del doLo veremos después de entender la solución a los ejercicios.exe.1 5) Interacción y análisis de archivos.1) genera la secuencia (5 4 3 2 1) for /l %i in (5.númeroFinal) do comando /L -> Iteración de un intervalo de valores. /L ejecutará la iteración mediante la comparación de númeroInicial con númeroFinal.1) do @echo %i Ejercicio [for-4]: Dar un barrido de ping a las primeras 30 ip’s desde 172. Recorre el árbol de directorios con raíz en [unidad:]rutaDeAcceso y ejecuta la instrucción for en cada directorio del árbol. Por ejemplo.0. Se utiliza una variable iterativa para establecer el valor inicial (númeroInicial) y.[opcionesDeLíneaDeComandos] /R -> Recursividad. Es decir un archivo de texto con el formato: notepad.-1.*) do @echo %~nxf Revisar el capítulo de “parámetros” para ver los prefijos ~n o bien ~x que pueden ponerse a parámetros (o bien a variables explícitas o implícitas en un for -son equivalentes a parámetros-) para entender el comando anterior. [for-2] Vamos a realizarlo en un script.16.-1.c:\Windows … etc… Ejercicio [for-3]: Obtener los mismos datos que en el ejercicio anterior pero recibiendo la carpeta origen por parámetro. Si númeroInicial es menor que númeroFinal.) sólo se enumerará el árbol de directorios. después. se considera el directorio actual. Ejercicio [for-2]: Se desea obtener en un fichero llamado c:\datos.txt ) endlocal Razonar el script y cada detalle dentro del for.1.!ruta:\.*”) do echo %%~nxf. @echo off setlocal enabledelayedexpansion set ruta= del c:\datos.númeroPaso. Si grupo tiene únicamente un punto (. recorrer un intervalo de valores especificado hasta que el valor sobrepase el valor final (númeroFinal) especificado.5) genera la secuencia 1 2 3 4 5 y (5.txt 2>&1 >nul for /r c:\windows %%a in (.=!\*. 4) for /L %variable in (númeroInicial. Si la variable iterativa sobrepasa el valor de númeroFinal. (1. También se puede utilizar un valor númeroPaso negativo para recorrer un intervalo de valores decrecientes. el comando se ejecutará. [for-3] . RESPUESTAS A LOS EJERCICIOS (1) [for-1] for %f in (c:\windows\*. Si no se especifica un directorio después de /R. el shell de comandos sale del bucle.” y el nombre de la carpeta en la cual residan.txt todos los archivos.=! >>c:\datos. Definición formal: El análisis de archivos se compone de la lectura de la información de salida. a continuación.Vamos a realizarlo en un script. Las líneas en blanco se omiten. su división en líneas individuales de texto y el análisis de cada línea en cero o más testigos. /F pasa el primer testigo separado por espacios en blanco de cada línea de cada archivo. @echo off setlocal enabledelayedexpansion if “%*” EQU “” goto error0 pushd cd “%*” >nul if errorlevel 1 goto error1 set ruta= del c:\datos. Las distintas sintaxis son: Sintaxis: for /F ["palabrasClaveDeAnálisis"] {%% | %}variable in (grupoNombreArchivos) do comando [opcionesDeLíneaDeComandos] for /F ["palabrasClaveDeAnálisis"] {%% | %}variable in (“cadenaLiteral”) do comando [opcionesDeLíneaDeComandos] for /F ["palabrasClaveDeAnálisis"] {%% | %}variable in (‘comando’) do comando [opcionesDeLíneaDeComandos] El argumento grupoNombreArchivos especifica uno o varios nombres de archivo.*”) do echo %%~nxf. Aconsejo una lectura rápida hasta la parte de “Ejemplos y comprensión del comando”. lee y procesa antes de pasar al siguiente archivo en grupoNombreArchivos. Es la parte más potente del FOR ya que permite ejecución interna de comandos dentro del propio “do” -realiza o puede realizar “spawn” del posible comando dentro del in-.1.txt 2>&1 >nul for /r “%*” %%a in (.!r! >>c:\datos. Cada archivo se abre.30) ping 172. se llama al bucle for con la variable de iteración establecida al valor del testigo. [for-4] for %i in (1. la cadena o el contenido del archivo. vamos a insistir en la comprensión real de su ejecución mediante ejemplos. pero sobre todo. Vamos a ver la definición formal y la sintaxis.txt ) goto FIN :error0 echo Falta parametro. Después. De forma predeterminada. Se trata de . Para suplantar el comportamiento predeterminado del análisis.) do ( set ruta=%%a&set r=!ruta:\.0.%i COMANDO ‘FOR’ INTERACCIÓN Y ANÁLISIS DE ARCHIVOS Hemos dejado aparte la interacción y análisis de archivos debido a que es la más compleja y a la vez la que más potencia da a los scripts y que usaremos en muchos de nuestros procedimientos. goto FIN :error1 echo Carpeta recibida por parametro inexistente goto FIN :FIN endlocal popd Razonar el script y cada detalle del uso del parámetro así como los controles realizados. especifique “palabrasClaveDeAnálisis”.=!&@for %%f in (“!r!\*.16. La tabla siguiente muestra la sintaxis opcional (para cualquier variable I): Variable con modificador Descripción %~I Expande %I que elimina las comillas (“”) delimitadoras.una cadena incluida entre comillas que contiene una o varias palabras clave que especifican diferentes opciones de análisis. tokens=x. skip=n Especifica el número de líneas que se omitirán al principio del archivo. delims=xxx Especifica un grupo de delimitadores. . %~zI Expande %I al tamaño del archivo. %~sI Expande la ruta de acceso para que solamente contenga nombres cortos. Reemplazo de variables: Se han mejorado los modificadores de reemplazo de las referencias a variables de for. Palabra clave Descripción eol=c Especifica un carácter de fin de línea (sólo un carácter). En la tabla siguiente se enumeran las combinaciones de modificadores que se pueden utilizar para obtener resultados compuestos.m-n Especifica los testigos de cada línea que se pasarán al cuerpo de for en cada iteración. %~tI Expande %I a la fecha y hora del archivo. %~pI Expande %I a una ruta de acceso solamente. %~fsI Expande %I a un nombre completo de ruta de acceso para que solamente contenga nombres cortos.y. %~fI Expande %I a un nombre de ruta de acceso completo. que una cadena incluida entre comillas se ejecutará como si fuera un comando y que una cadena escrita entre comillas simples es un comando de cadena literal. %~xI Expande %I a una extensión de archivo solamente. se asignarán nombres de variable adicionales. este modificador se expande a la cadena vacía. La forma m-n es un intervalo que especifica los testigos m hasta n. Variable con modificadores combinados Descripción %~dpI Expande %I a una letra de unidad y una ruta de acceso solamente. Si el nombre de la variable de entorno no está definido o la búsqueda no encuentra el archivo. formado por los caracteres espacio y tabulador. %~dI Expande %I a una letra de unidad solamente. %~nxI Expande %I a un nombre y extensión de archivo solamente. %~aI Expande %I a los atributos del archivo. Si el último carácter de la cadena tokens= es un asterisco (*). %~nI Expande %I a un nombre de archivo solamente. %~$PATH:I Busca los directorios enumerados en la variable de entorno PATH y expande %I al nombre completo del primero encontrado. utilice una de las sintaxis siguientes: for /F ["usebackqpalabrasClaveDeAnálisis"] {%% | %}variable in (“grupoNombreArchivos”) do comando [opcionesDeLíneaDeComandos] for /F ["usebackqpalabrasClaveDeAnálisis"] {%% | %}variable in (‘cadenaLiteral’) do comando [opcionesDeLíneaDeComandos] for /F ["usebackqpalabrasClaveDeAnálisis"] {%% | %}variable in (`comando`) do comando [opcionesDeLíneaDeComandos] En la tabla siguiente se enumeran las palabras clave de análisis que se pueden utilizar para palabrasClaveDeAnálisis. Como consecuencia. Si incluye la opción usebackq. Reemplaza el grupo de delimitadores predeterminado. usebackq Especifica que se pueden utilizar comillas para incluir los nombres de los archivos de grupoNombreArchivos. se asigna una variable adicional que contendrá el texto que queda en la línea después del último testigo analizado. abc o bien por ???. que se pasa a un comando Cmd. ya que mediante el comando type podríamos obtener resultados similares. * Ejemplos y comprensión del comando Hasta el momento. únicamente he copiado la definición formal que figura en la propia ayuda de Windows. En los ejemplos anteriores se puede reemplazar %I y PATH por otros valores válidos. para ello. grupoNombreArchivos se considerará como una única línea de entrada de un archivo y se analizará así. para poder seguir lo que está haciendo).exe secundario y la información de salida se captura en la memoria y se analiza como si fuera un archivo.txt) do … lo que queramos El comando anterior leerá todos los ficheros enumerados en la cláusula ‘in’ del directorio en curso y el contenido de ellos.txt) do @for /f %j in (%i) do @echo %j (recordemos igualmente que las @ son para no ver la expansión del comando. que no distinguen entre mayúsculas y minúsculas.abc pr1. podremos endentar dos for para hacerlo. Cuando estemos depurando una instrucción lo normal es no ponerlas. el código resultará más legible y evitará confusiones con los modificadores. para ello. línea por línea. Queremos el resultado anterior pero ignorando la primera línea de cada archivo. Compliquémoslo un poco. Nótese igualmente que esta sintaxis del for no admite caracteres “comodín” en los nombres de archivo. Para ignorar n líneas de un archivo pr. se debe escribir entre comillas el grupoNombreArchivos que está entre paréntesis. Si utiliza nombres de variables en mayúsculas como %I. es tan sencillo como usar: for /f %i in (pr. De esta forma. Analizar la información de salida: El comando for /F se puede utilizar para analizar la salida de un comando. pero viéndolo con un for nos ayuda a comprender el propio for. ¿Cómo podríamos entonces hacer para ver el contenido de todos los archivos con extensión abc? Bien. línea por línea lo pasará dentro de la variable i al do de ejecución. Analizar una cadena: También se puede utilizar la lógica de análisis for /F en una cadena inmediata. for %i in (*.abc *. Así se considerará como una línea de comando.txt) do @for /f “skip=1″ %j in (%i) do @echo %j Sigamos complicándolo un poco más con un ejemplo real: imaginemos que somos administradores de una red y queremos que no se use el emule (o cualquier otro programa) en nuestra red. Recordemos que en un script el %i debe sustituirse por %%i. Voy a darle ahora una vuelta e intentar explicarlo bajo dos puntos de vista que son los básicos de cara a la ejecución de un script: 1) Lectura del “contenido” de un fichero o ficheros Leer el contenido de un fichero. seria tener un script en nuestra máquina que periódicamente “matase” los procesos que queramos en las máquinas remotas.abc) En nuestro ejemplo. usando un poco la imaginación y sabiendo que el for normal (sin /f) es capaz de enumerar los archivos en un directorio.abc *. Evidentemente este es un ejemplo poco agraciado.abc sería: for /f “skip=n” %i in (pr. no podemos referenciarlos por *.%~dp$PATH:I Busca los directorios enumerados en la variable de entorno PATH de %I y se expande a la letra de unidad y ruta de acceso del primero encontrado. Una manera sencilla sin entrar a modificar las políticas. sino que el nombre debe estar totalmente cualificado.abc. escriba entre comillas simples el grupoNombreArchivos (es decir. Los nombres de variable válidos de for terminan con la sintaxis %~. %~ftzaI Expande %I a una línea de salida parecida a la de dir. es decir. por tanto: for %i in (*. La primera idea es que tenemos que tener un fichero con la lista de las máquinas en las cuales . ‘grupoNombreArchivos’) que está entre paréntesis. 0. ejecutarlas en consola para ver cómo son dichas salidas y preparar un script similar con ellas. Llamemos a ese fichero “máquinas. Igualmente recordemos un par de comandos de XP Profesional o bien de W2003. Deseamos que el script reciba por parámetro el usuario y nos solicite por pantalla la password de ese administrador. Como ejercicio. De esta manera. Podemos verlo ejecutando en una consola taskkill /? Bien. simplemente añadiendo en uno de los ficheros una nueva máquina o en el segundo fichero un nuevo programa.* delims= ” %%g in (‘tasklist /S %1 /U %user% /P %pass%’) do ( call :proc01 %1 %%g %%h ) goto :EOF :proc01 for /f %%i in (programas. creamos un fichero uno con el nombre de las máquinas.168.txt emule. os podéis bajar dichas utilidades. Para ver los programas que están en ejecución en una máquina. simplemente teclear en una consola de comandos tasklist. Para ello. ya tenemos todos los ingredientes. Esto nos muestra la lista de procesos y su PID (número único que identifica un proceso).exe bittorrent. Las otras máquinas no se enterarán de nada… pero los programas p2p se le “morirán” cada 5 minutos misteriosamente. con el nombre de programas que queremos “matar”. Sea este fichero: programas. se necesita un usuario / password administrador en las máquinas remotas. Ahora ya es trivial la resolución: @echo off if {%1} EQU {} (echo Falta usuario&goto :EOF) setlocal enabledelayedexpansion set user=%1 set /p pass=”password del usuario %1 : ” cls for /f %%f in (máquinas.com existe una utilidad llamada pskill. (Este ejemplo es valido sin cortafuegos.txt” en el cual escribiremos los nombre o direcciones IP de las máquinas: \\KA0001 \\192.sysinternals.exe Debido a que vamos a acceder a máquinas remotas.queremos controlar los procesos. En www.10 Igualmente crearemos un fichero dos.2. Además. deberíamos tener otro dichero con la lista de programas que queremos “matar”. Con cortafuegos deberemos tener abiertos el puerto netbios-ssn que es el que usan los comandos tasklist y taskkill). pslist las cuales también funcionan en XP Home (que no posee los comandos anteriores). Vamos a comentar algunas características usadas en el script anterior: .txt) do if {%2} EQU {%%i} taskkill /S %1 /U %user% /P %pass% /PID %3 goto:EOF Podemos modificar el script para no solicitar la password y recibirla también por un segundo parámetro y ponerlo en el planificador de tareas para que se ejecute por ejemplo cada 5 minutos. podremos tener siempre planificado un script único que periódicamente analice en las máquinas especificadas en el fichero uno y mate los procesos especificados en el fichero dos.txt) do call :proc00 %%f endlocal goto :EOF :proc00 for /f “skip=2 tokens=1. Recordemos también que el comando taskkill es capaz de matar un proceso pasándole como parámetro el PID del programa a “matar”. cmd) que haga: @echo off dir .exe 564 Console 0 5. especificamos algo encerrado entre comillas simples lo que estamos haciendo es ordenando que se ejecute ese comando en un cmd aparte y que cuando finalice. b) En tokens. Creo que con este pequeño resumen puede comprenderse perfectamente la potencia del for.2. La salida a consola (STDOUT) de ese comando cuando finalice. le estamos indicando que vamos a coger el primer campo (que lo pondrá en %%g).512 K services. Evidentemente toda esa salida (probarla por pantalla) debe filtrarse para separar los campos que necesitamos. la salida que nos mostraría en pantalla (STDIN) de la pase al for directamente. será la que se pase línea por línea al for invocante. Esto lo veremos en detalle en la parte 2) de este capítulo.848 K winlogon.exe 412 Console 0 644 K csrss.* delims= ” %%g Con esto le estamos diciendo: a) Que ignore las dos primeras líneas. Cuando dentro de un for /f en la parte del in. si ejecutamos tasklist en nuestra máquina veremos algo así: Image Name PID Session Name Session# Mem Usage ================ === ================ ======== ============ System Idle Process 0 Console 0 24 K System 4 Console 0 252 K smss. Vamos a ver cómo se realiza esto y cómo se recuperan los datos: Lo existente entrecomillado simple dentro de un in en un comando for /f se ejecutará abriendo (en forma oculta) otro “cmd” el cual ejecutará el comando. Es decir. De esta manera vemos cuantos cmd. Hay una manera de comprobar esto. Abrimos un administrador de tareas y ordenamos por el “Nombre de imagen” -pinchado ascendente o descendentemente. Fijémonos que sólo hemos definido %%g en la línea.* delims= ” %%g in (‘tasklist /S %1 /U %user% /P %pass%’) do… Está recuperando en %%g el nombre de cada proceso y en %%h el PID de dicho proceso. ya que primero: nos molestan las líneas de cabecera y segundo: en las líneas de detalle tenemos que separar lo que es el nombre del programa de lo que es el PID y el resto de datos (que nos sobran en este caso). Por tanto la instrucción: for /f “skip=2 tokens=1.exe tenemos en ejecución. Analizar despacio ahora el resto del script. pero al especificar más campos. 2) Ejecución de “instrucciones o comandos” dentro del for (en la cláusula in) Hemos introducido anteriormente en el ejemplo de la parte 1) que dentro del “in” puede ir entrecomillado simple el nombre de un programa o comando y que el sistema lo ejecutará. (que lo pondrá en %%h) y el resto (que lo pondrá en %%i). el segundo. Por tanto es como si se ejecutase el tasklist y lo que se vería por pantalla se le pasa al for.exe 524 Console 0 5.208 K ………. Fijémonos ahora por delante de la cláusula “in” que es lo que hay: “skip=2 tokens=1.exe 608 Console 0 6.2. Ahora nos creamos un simple script (pr. por tanto en nuestro caso le estamos diciendo que sólo hay un delimitador y que este delimitador son los espacios en blanco.in (‘tasklist /S %1 /U %user% /P %pass%’) Fijémonos en la comilla simple que delimita al comando tasklist y sus parámetros. le estamos diciendo que considere delimitadores los caracteres que van a continuación del símbolo igual. c) en delims= (nótese un espacio en blanco al final).en la pestaña procesos. usará las letras alfabéticamente a partir de %%g como nombres de variables. ..exe” más en ejecución de forma oculta ya que no hay consola que veamos.Includes 8. todavía no ha devuelto contenido al for.Funciones 7.Imprimir caracteres de comandos.Algunas otras variables de Entorno.Misc 9. Lo primero que vemos es que se queda parado. la fecha. Nuestro for todavía no ha devuelto datos. redirige también el STDIN). 1.EOF Variables y Argumentos El manejo de variables en batch.. y este nos permite hacer desde operaciones matemáticas. Fijémonos también en el administrador de tareas: hay un “cmd. Si ahora tecleamos cualquier cosa en la única consola que tenemos abierta..IF 5.. Programación BATCH Avanzada. por tanto. asi como reemplazar cadenas de texto.. es muy flexible. en la segunda consola (oculta) al recibir la tecla.cmd y está parado en la instrucción “pause”. y sus propiedades. continúa y finaliza... En vez de ejecutarlo directamente vamos a ejecutarlo desde dentro de un for for /f “tokens=*” %i in (‘pr. línea por línea al for. Los argumentos que recibe un batch. y que realmente es el que esta ejecutando el pr.cmd’) do @echo %i El ejecutar lo anterior ¿qué pasa? Ejecutémoslo. generar numeros aleatorios. 4.cmd se ha ejecutado. aunque el dir del pr. son recibidos de la siguiente forma: batch argumento1 dos tres hara que: %0 = batch %1 = argumento1 %2 = dos %3 = tres .. 2.Variables y Argumentos. En el momento de la finalización es cuando devuelve los datos. 3. hasta seleccionar ciertas partes de una variable. En ese momento. Temario.. hora. y obtener archivos.pause Esto sacaría un “dir” y esperaría hasta que pulsemos una tecla.FOR 6. esta entrada se pasará al segundo cmd (es decir. entre otros.. regresa solo el nombre de archivo %1.regresa solo la ruta. . el nombre del archivo. 4. con directorios. C:\Documents and Settings\Administrador\tempcurso>astring 123 456 789 2. astring 456 789 4.regresa solo la extension del archivo %1. Podemos borrar el contenido de un parametro con el comando shift: Código 1. Tambien contamos con los siguientes modificadores para los archivos: Código 1.regresa los atributos del archivo. El volumen de la unidad C no tiene etiqueta. 2. C:\Documents and Settings\Administrador\tempcurso>dir 2. . . 10.regresa la letra de la unidad de %1. con nombres cortos del archivo %1. 3. shift borro. . 3. 7.regresa la hora/fecha del archivo %1 .regresa solo la ruta del archivo %1. 8.en %0 se guardara. por ejemplo: en un directorio donde tenemos: Código 1. 6. . @echo off echo %0 %1 %2 %3 shift /1 echo %0 %1 %2 %3 al llamar: Código 1. astring 123 456 789 3. . . %~f1 %~d1 %~p1 %~n1 %~x1 %~s1 %~a1 %~t1 %~z1 . 5.regresa el tamaño del archivo %1. el primer argumento.regresa la ruta y el archivo de %1. 2. 5. 4. . 9. echo Ruta Corta: %~s1 8.088 bytes libres 12.echo Tamaño: %~z1 11. Ruta al archivo: C:\Documents and Settings\Administrador\tempcurso\archivo. Tambien podemos usar varias propiedades. Fecha: 24/07/06 12:25a 10.txt 8. echo Extension: %~x1 7. 7. 1 archivos 6 bytes 11. saca el siguiente resultado: Código 1.txt 7.Tama±o: 6 11. 9. echo Solo ruta: %~p1 5. Solo ruta: \Documents and Settings\Administrador\tempcurso\ 5. 5. este batch: Código 1.. Directorio de C:\Documents and Settings\Administrador\tempcurso 6. 24/07/2006 12:25a <DIR> 8.bat.3. Nombre: archivo 6. echo Disco: %~d1 4. Atributos: --a-----9. este codigo: Código . echo Ruta al archivo: %~f1 3. Extension: .161.txt 10. 24/07/2006 12:25a 6 archivo. echo Nombre: %~n1 6. echo Atributos: %~a1 9. 2 dirs 401.715. Ruta Corta: C:\DOCUME~1\ADMINI~1\TEMPCU~1\archivo. echo Fecha: %~t1 10. por ejemplo.txt 2. llamandolo analiza. @echo off 2. C:\Documents and Settings\Administrador\tempcurso>analiza archivo. 24/07/2006 12:25a <DIR> . El número de serie del volumen es: A057-553B 4. Disco: C: 4.txt 3. . se debe poner entre comillas. Si lo que recibimos no es un archivo. @echo off . echo Con Comillas: %1 3. C:\Documents and Settings\Administrador\tempcurso>astring "parametro de varias letras" 2. @echo off 2. echo Sin Comillas: %~1 4. que contiene mas de una palabra. echo %~anxt1 4. en %1. --a-----.1. se usa: %* es decir: Código 1. lo recibimos con comillas.txt 2. si queremos obtener todos los argumentos. saca este resultado: Código 1. pero si usamos: Código 1.txt 3. 3. saca este resultado: Código 1. Con Comillas: "parametro de varias letras" 3.24/07/06 12:25a archivo. Y por ejemplo. algo asi: astring "parametro de varias letras" al obtenerlo. sino una cadena de texto. @echo off 2. Sin Comillas: parametro de varias letras 4. C:\Documents and Settings\Administrador\tempcurso>analiza archivo. puedes usar: set /P variable= por ejemplo: Código 1. el valor de algo escrito por el usuario.Como te llamas? Juan Tu te llamas Juan Ahora. hacer algo como. 3. 2. queremos. 2.2. 3. Argumentos: parametro de varias letras Para asignar a una variable. C:\Documents and Settings\Administrador\tempcurso>astring parametro de varias letras 2. 6. echo Argumentos: %* 4. si por ejemplo. C:\Documents and Settings\Administrador\tempcurso>astring ┐. 4. al ejecutar: astring parametro de varias letras nos regresa: Código 1. @echo off echo ¿Como te llamas? set /P miva= echo Tu te llamas %miva% hara algo asi: Código 1. 5. 4. obtener las ultimas 3 letras del nombre: Código 1. @echo off . 3. 5. esto: %NOM:~1. + .3% obtendra del segundo al cuarto caracter. 4. echo Escribe tu Nombre 3. por ejemplo. de esta forma: Código 1. () 2. 3. @echo off echo Escribe una frase set /P FRA= echo %FRA:e=XXX% esto reemplazara las letras "e" por "XXX". 3. 5. como si se tratara de la funcion substring. 2. recuerda) Para reemplazar cadenas. obtener los ultimos 3 caracteres. * / % 3. dentro de otra variable.operadores aritméticos .2. 4. Aqui lo que estamos haciendo en la ultima linea: %NOM:~-3% hara.agrupar . se usa el modificado /A.operadores aritméticos . set /P NOM= 4. 2. es la siguiente sintaxis: Código 1. @echo off set /A x=1 echo %x% set /A x=x*9 echo %x% tenemos las siguientes operaciones disponibles: Código 1. echo %NOM:~-3% 5. Para hacer calculos matematicos. (empiezas desde 0. 6. 4.::Esto imprimira el valor de x entre %% 15. set pru=HOLA 4. echo %x% 7.asignación 9. . siempre usamos los signos % Como imprimes uno? veamos: Código 1. :: Esto imprimira el contenido de x 6. @echo off 2.mayús lógica 5. 14. Imprimir caracteres sin usar comandos Ahora. ::Esto imprimira la letra x 9. en las variabes. 3.AND . @echo off set /A x=2 echo %x% set /A x=x*0xff echo %x% al colocar 0x estamos especificando.XOR 6. = *= /= %= += -= .4.separador de expresión 11. &= ^= |= <<= >>= 10.OR 7. & . ^ . se preguntaran. que a continuacion se pondra un valor hexadecimal. 11. echo x 10. set x=pru 3.. << >> . 2. | 8. 8.::Esto imprimira %x% 12.echo %%%x%%% .echo %%x%% 13. 5. Con este podemos usar numeros hexadecimales de la siguiente forma: Código 1. 5. 17.:: Lo mismo 18. echo ^<html^>^<h1^>Hola^</h1^>^</html^> >index.echo %pru% 19. deben colocarlo 2 veces. que ejecutan alguna accion en batch como: & | < > debes colocar este caracter antes:^ por ejemplo: Código 1. pero: Código 1.echo %%pru%% 20. el caracter %. <html><h1>Hola</h1></html> 3.echo %%%pru%%% 21.html 2. echo <html><h1>Hola</h1></html> >index.html 2.html 2.16. si quieren imprimir. Algunas otras variables de entorno . dara: Código 1. Para otros caracteres. En resumen. no funcionara. C:\Documents and Settings\Administrador\tempcurso>type index. 6. @echo off echo %CD% PUSHD \ echo %CD% POPD echo %CD% PUSHD funciona de la siguiente manera: Guarda el directorio actual. y va a la ruta especificada.33 5.Tenemos otras variables de entorno que podrian servir. Directorio Actual: C:\Documents and Settings\Administrador\tempcurso 3. 2. por ejemplo: Código 1. Fecha: Lun 24/07/2006 10. 4. 4.60 11. 6.Hora: 2:13:51. por ejemplo: Código 1. C:\Documents and Settings\Administrador\tempcurso>astring 8. 3. que sirven para guardar y regresar al directorio actual. Directorio Actual: C:\Documents and Settings\Administrador\tempcurso 9. Otras instrucciones muy utiles.. serian POPD y PUSHD. @echo off echo Directorio Actual: %CD% echo Fecha: %DATE% echo Hora: %TIME% echo Numero Aleatorio: %RANDOM% dara como resultado: Código 1. 7. 3. 5. C:\Documents and Settings\Administrador\tempcurso>astring 2. Numero Aleatorio: 24523 6. Fecha: Lun 24/07/2006 4. Hora: 2:13:49. 2. 7. 5. POPD regresa al directorio guardado por PUSHD . ademas de las comunes de ALLUSERSPROFILE y HOMEPATH.Numero Aleatorio: 3681 12. tambien podemos comparar cadenas. IF "%~1"=="hola" echo hola 3. reconoce varias situaciones: valores de error comparar cadenas existencia de archivos comparaciones matematicas como ya sabemos %ERRORLEVEL% almacena algunos valores de otras funciones. asi: Código 1. @echo off 2. al hacer IF ERRORLEVEL 1 @echo ok ELSE @echo no estariamos preguntando si ERRORLEVEL es 1. por ejemplo: Código 1. POPD 8. echo %CD% 5. . echo %CD% 7. @echo off 2. echo %CD% 3. IF If. echo %CD% 9. si no. PUSHD %homepath% 6.echo %CD% 11.podemos usarlos uno dentro de otro. si lo es imprime OK. imprime NO. POPD 10. PUSHD \ 4. 3. 2. 4.igual NEQ . no salga error Código 1.menor que LEQ . debemos usar los siguientes codigos de comparación: Código 1. @echo off 2. si vamos a usar comparaciones numericas. IF /I "%~1"=="hola" echo hola 3. ahora. 2. 7. echo Cual es tu edad? .menor que o igual GTR . 4. 6. 5. 7. este codigo. 6. 9. EQU . @echo off 2.mayor que o igual por ejemplo: Código 1.mayor que GEQ . 5.no igual LSS . podemos usar IF en varias lineas: Código 1. @echo off IF EXIST %~snx1 ( echo EXISTE! ) ELSE ( echo NO EXISTE ) con parentesis (). 8. solo responde si dices hola CON minusculas.usamos %~1 para que aunque el usuario ponga comillas. /I es para hacer mas estricta la comparacion. 3. SET /P m= IF %m% GEQ 18 ( echo ERES MAYOR DE EDAD ) ELSE ( echo NO ERES MAYOR DE EDAD ) que regresa: Código 1. nos permite analizar segmentos de la salida de comandos. Cual es tu edad? 3. IF DEFINED var ( echo SI ) ELSE ( echo NO ) FOR FOR es una herramienta muy completa. 2. 4. Cual es tu edad? 8. 4. 6. C:\Documents and Settings\Administrador\tempcurso>acon 7. 8.3. Tambien permite hacer bucles de la siguiente manera: Código . 7. 19 4. 6. NO ERES MAYOR DE EDAD 10. Tambien podemos saber si una variable ya fue definida: Código 1. ERES MAYOR DE EDAD 5. 3. C:\Documents and Settings\Administrador\tempcurso>acon 2. 9. 5. 5. 17 9. funciones y el contenido de archivos. 6. incremento es la cantidad a sumar.─. es para numerar archivos.─.─. 5.─. por ejemplo: Código 1.fin) DO (acciones) inicio. para SOLO mostrar directorios: Código 1. FOR /R /D %%x in (a*) DO echo %%x 2. ├.─.. es el valor inicial.─.10) DO (echo %%i) imprimira 0 1 2 3 4 5 6 7 8 9 10 sinembargo. que empiesen con m.─. y fin es la cantidad a detenerse. FOR %%x in (x*) DO echo %%x mostrará todos los archivos que empiezan con x.xx └. con el comando "/R".hola al ejecutar el comando: Código 1.─. la forma mas sencilla de usar FOR. └. FOR /L %%i IN (0.─.adios │.─. C:\adios\algo . C:\adios 3. FOR /D %%x in (m*) DO echo %%x el modificador "/D".─. es decir. que se ejecute dentro de cada directorio. por ejemplo. El comando se puede hacer "recursivo". └. en una estructura de directorios como la siguiente: Código 1.1. FOR /L %%var IN (inicio. 4.algo │. por ejemplo: Código 1.incremento. 2.1.─. 3. mostrará solo los directorios. y hacer algo con ellos. 2-6. incluso podriamos hacer un buscador en batch. delims -> esto sirve para separar las strings. 1.9* regresara 4 segmentos.txt C:\hola\ax. si no se coloca esta opcion. 8.. . 4. 3. FOR /R %%x in (*x*) DO echo %%x C:\ax. desde el segundo hasta el sexto. FOR /F ["opciones"] %var IN (conjunto) DO (acciones) conjunto puede ser: conjunto de archivos -> sin comillas cadena de caracteres -> con comillas dobles (" ") comando -> con comilla simple (' ') las opciones son las siguientes: eol -> todo lo que este despues de este caracter sera ignorado (para cada linea) skip -> numero de lineas a saltarse al principio del archivo/comando. seran pasados a las variables. despues del noveno. /F que nos permite usar ciertas opciones para separar el resulado de las acciones. comandos.txt nos mostrara todos los archivos que coinciden con la sequencia especificada. 7. delimitados por "delims".8. Su sintaxis es la siguiente: Código 1.txt C:\adios\algo\kkx. cadenas.sinembargo. 2. Código 1. 5..txt C:\adios\algo\xx\xx. el primero. el signo de menos (-) genera intervalos. Tenemos otro modificador.. o archivos.. con el uso de FINDSTR y FOR. el primero y todo lo que este despues (el * regresa todo el resto de la linea) 1. por ejemplo: 1.txt C:\hola\rx. se usaran como separadores "espacio" y "tab" tokens -> esto es para especificar cuales segementos.2.2* pasara 2 segmentos. al ejecutar el comando. el octavo y el resto de la linea.txt C:\adios\wwx.txt C:\adios\sx. 6.3 solo pasara los primeros 3 segmentos. 10* delims= " %%i IN ("George no es malvado. 6. esta la opcion: usebackq -> que cambia la forma de interpretar si es string o comando. sinembargo una etiqueta puede servir de funcion y recibir parametros. de etiquetas y de filtros nos ayuda mucho al momento de escribir un codigo. el siguiente programa: Código 1. 4. siempre piensa en matar a los demas. es tonto. @echo off call:funcion 1 2 3 call:funcion %* goto:EOF :funcion echo Estoy en: %~nx0-^>%0 %* al ser llamado. el siguiente comando: Código 1. FOR /F "tokens=1.por ultimo.") DO echo %%i %%j %%k %%l tonto. miren. George es malvado. 3..3-5. es bondadoso. Muchos creen que las etiquetas solo sirven para los goto. de la siguiente manera: 'cadena' `comando` Nota: [`] es diferente al caracter de acento [´] por ejemplo. %%m %%n %%o matar a %%p %%q dara de resultado: Código 1. 5. 2. Funciones El uso de argumentos. por ejemplo en: .7-9. siempre piensa en los demas. echo su resta es: . "return". :suma 4. 8.set /A res=%1 * %2 15. 3. 18.echo su suma es: 22.echo %res% 11. 24. set /A res=%1 .. echo %res% 6. todo es igual a usar goto a excepcion del uso de argumentos.bat->:funcion 1 2 3 3.call:suma %arg% 23.echo %res% 16. hasta ahora.set /P arg=Escribe 2 numeros separados por un espacio 20.goto:EOF 12. en situaciones como: Código 1. se hace usando: goto:EOF entonces.goto:EOF 17. si queremos hacer un. 13. Estoy en: ejemplo. sinembargo. C:\>ejemplo 2.%2 10.:main 19. Estoy en: ejemplo.. C:\>ejemplo HOLA MUNDO 2. Estoy en: ejemplo.Código 1..bat->:funcion HOLA MUNDO la funcion obtiene tambien los argumentos del programa. Estoy en: ejemplo.echo %arg% 21. goto:EOF 7.:multiplica 14.bat->:funcion el primero muestra los parametros enviados por el batch (1 2 3). @echo off&call:main&goto:EOF 2. y el segundo los parametros enviados al programa. :resta 9.bat->:funcion 1 2 3 3. en este otro ejemplo: Código 1. set /A res=%1 + %2 5. 27.. 4 8.call:multiplica %arg% 29.25. Escribe 2 numeros separados por un espacio 6 2 3. por ejemplo: . debe de estar al principio: @echo off&call:%*&goto:EOF queda algo asi: Código 1. su suma es: 5. 30. @echo off&call:%*&goto:EOF :funcion1 .. su resta es: 7. 6 2 4.bat funcion argumentos y en el archivo a incluir.. el resultado es algo asi: Código 1.goto:EOF 31. Includes Para hacer un "include" oincluir un archivo.echo su producto es: 28. 4. C:\>operaciones 2.call:resta %arg% 26. 5. 3. 8 6. 2. su producto es: 9. como podemos ver goto:EOF se usa para regresar al orden de comandos. solo debes llamarlo asi: archivo_a_incluir.. :funcion2 . 6. 12 10. 5. @echo off if "%~1"=="" ( inclu.echo uso: 12.bat-Código 1.echo Hola %* 17. echo # sirdarckcat # 7.bat uso ) else ( inclu. --inicio. 15. 4.bat Nombre . 4. 3.bat-Código 1.goto:EOF 18. echo ############### 8.goto:EOF 14.echo %~nx0 Nombre 13.:nombre 16. C:\>inicio ############### # Hecho por: # # sirdarckcat # ############### uso: inclu. 8. 6. 7.bat cabeza inclu. echo ############### 5. 3. 5. goto:EOF 9. 10.:uso 11.bat nombre %~1 ) esto daria este resultado: Código 1. 3. 7. 2. 2. :cabeza 4. echo # Hecho por: # 6.--inclu. 6. @echo off&call:%*&goto:EOF 2. Misc Algunos filtros y comandos interesantes: • comando | more muestra el resultado del comando de forma paginada • comando | sort muestra el resultado del comando de forma ordenada • TITLE "algo" cambia el titulo de la ventana de CMD • SUBST ruta/a/alguna/carpeta [letra_unidad] asgina a letra_unidad la ruta de acceso • FIND "cadena" busca cierta cadena en un archivo (se puede usar como filtro). (para mas info. y busqueda general (lo mas parecido que DOS tiene a grep).Hola sirdarckcat 11. escribe en CMD: FIND /?) • FINDSTR extension de FIND. [/F:archivo] 5. 8. con el modificador /v encuentra solo las que NO tienen la linea especificada. /B Hace coincidir los modelos si están al principio de la línea. C:\>inicio sirdarckcat 10.]] 7. 9. 2. 12. acepta expresiones regulares.. Busca cadenas en los archivos. descripción detallada: Código 1..8. . FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] 4.C:\> 13. [cadenas] [[unidad:][ruta]nombredearchivo[ . 3. [/C:cadena] [/G:archivo] [/D:lista de directorios] [/A:atributos de color] 6. 12. 37.y' 39. 29. [unidad:][ruta]nombredearchivo 35. 27.y. /N Imprime el número de la línea antes de la línea que coincide. . 58. /C:cadena Utiliza una cadena especificada como una búsqueda de cadena 28. $ Posición de línea: fin de línea 47. 55. cadenas Texto que se debe buscar. /L Literalmente utiliza cadenas de búsqueda. ^ Posición de línea: comienzo de la línea 46. 36.FINDSTR referirse al Comando de referencia Command en línea. (/ significa consola). [clase] Clase de carácter: cualquier carácter en la serie 48. /O Imprime un carácter de desplazamiento antes de las líneas que 21. /E Hace coincidir los modelos si están al final de la línea. /F:archivo Lee la lista de archivos desde el archivo especificado 26. 57. 34. * Repetir: cero o más ocurrencias de un carácter previo o de clase 45. 22. /P Omite archivos con caracteres que no son imprimibles 23. /X Imprime líneas que coinciden con exactitud.Utiliza espacios para separar múltiples cadenas de búsqueda a no ser que 38. .el argumento lleve un prefijo con /C. 30. /A:attr Especifica atributos de color con dos dígitos hexadecimales. 11.y.Expresión regular de referencia rápida: 43. correspondencia. Ver 24. Comodín: cualquier carácter 44. 'FINDSTR /C:"qué tal" x. 16. xyz\> Posición de palabra: fin de palabra 54. directorios 33. [x-y] Intervalo: cualquier carácter que esté dentro del intervalo 50. literal. [^class] Clase inversa: cualquier carácter que no esté en la serie 49. 17. /D:dir Busca un signo de punto y coma de la lista delimitada de 32. \<xyz Posición de palabra: principio de palabra 53. /R Utiliza cadenas sde búsqueda como expresiones regulares. Especifica un archivo o archivos que buscar. coinciden. \x Escape: uso literal de un metacarácter x 52.y' busca 40.busca "qué" o "tal" en el archivo x. "color /?" 25. los subdirectorios. 41. 14. 10. /S Busca archivos que coinciden en el directorio actual y en todos 13. 15. Por ejemplo. 31. /I Especifica que la búsqueda no distingue mayúsculas de minúsculas. 'FINDSTR "qué tal" x."qué tal" en el archivo x. 18. especificado 51.Para obtener una información más completa sobre expresiones regulares de 56. /V Sólo imprime líneas que no contienen una correspondencia. 20. 42. /M Sólo imprime el nombre de archivo si el archivo contiene una 19.9. /G:archivo Coje la búsqueda de archivos desde el archivo especificado (/ significa consola). El programa se inicia en una zona de memoria compartida Iniciar en prioridades: /LOW . . /B . y espera hasta que termine de ejecutarse por ejemplo.• start "titulo ventana nueva" [OPCIONES] comando argumentos START tiene mas opciones de las que son usadas comunmente.normal /HIGH . es decir las modificaciones al entrono hechas en esta sesion. y en %windir% EOF EOF es una etiqueta que define el fin del archivo. si quieren abrir un programa sin generar una ventana. por ejemplo netcat. no afectaran el nuevo programa /MIN .tiempo real /ABOVENORMAL .baja /NORMAL . las opciones entre otros contienen: /Druta .La nueva ventana se inicia minimisada /MAX .se inicia la aplicacion con el entorno original.La nueva ventana se inicia maximisada /SEPARATE .sobre lo normal /BELOWNORMAL . sirve para terminar funciones.alta /REALTIME .Inicia el programa. en el contexto original. "titulo ventana nueva" especifica el titulo de la ventana que se generará. solo sirve para terminar el documento . con prioridad alta. espero les sirva TITLE cadena Fija el título de la ventana en la ventana del símbolo del sistema.debajo de lo normal /WAIT . podrian hacer algo asi: start /B /SEPARATE /HIGH /I /D %WINDIR% nc -L -p 1337 |exit que lo inicia en una zona de memoria separada.El programa se inicia en una zona de memoria separada /SHARED ..el programa inicia en el directorio.la aplicación se inicia sin ventana /I . y en este caso. un carácter por cada nivel insertado. el modificador de línea de comando o el valor del registro DefaultColor. En el símbolo del sistema se pueden escribir caracteres normales y los siguientes códigos especiales: $A $B $C $D $E $F $G $H $L $N $P $Q $S $T $V $_ $$ & (Símbolo de unión) | (barra vertical) ( (Paréntesis izquierdo) Fecha actual Código de escape (código ASCII 27) ) (Paréntesis derecho) > (signo mayor que) Retroceso (elimina el carácter previo) < (signo menor que) Unidad actual Unidad y ruta de acceso actual = (signo igual) (espacio) Hora actual Versión de Windows XP Retorno de carro y alimentación de línea $ (signo del dólar) Si las Extensiones de comando están habilitadas. texto Especifica un nuevo símbolo del sistema. $M Muestra el nombre remoto asociado a la letra de unidad actual o la cadena vacía si la unidad actual no es una unidad de red.exe. el comando PROMPT admite los siguientes caracteres de formato adicionales: $+ cero o más caracteres de signo "más" (+) en función de la profundidad del directorio de pila PUSHD.EXE. este comando restaura el color que teníacuando se inició CMD. 0 = Negro 8 = Gris 1 = Azul 9 = Azul claro 2 = Verde A = Verde claro 3 = Aguamarina B = Aguamarina claro 4 = Rojo C = Rojo claro 5 = Púrpura D = Púrpura claro 6 = Amarillo E = Amarillo claro 7 = Blanco F = Blanco brillante Si no se indican argumentos. el segundo al texto.PROMPT [texto] Cambia el símbolo del sistema de cmd. COLOR nº1nº2 Configura los colores predeterminados de primer y segundo planode la consola. Este valor proviene de la ventanade la consola. Especificados con dos dígitos hex: el primero corresponde al fondo. . El evaluador de expresiones esbastante simple y es compatible con las siguientes operaciones. CHCP [nnn] nnn Especifica una página de códigos. establece o quita las variables de entorno de cmd. El comando SET no permitirá que un signo de igual sea parte de una variable. Escriba CHCP sin parámetro para mostrar el número de la tabla de códigos activa.exe. SET cambia así: "Cuando se llama al comando SET solamente con un nombre de variable. GRAFTABL [xxx] Permite que Windows muestre caracteres extendidos en modo gráfico. cadena Especifica una serie de caracteres que se asignará a la variable.El comando COLOR configura ERRORLEVEL a 1 si se realiza un intento de ejecutar el comando COLOR con el mismo color de primer y segundo plano BREAK: Activa o desactiva Ctrl+C extendido en DOS Está presente para que haya compatibilidad con sistemas DOS. Si se activan las extensiones de comando y se ejecuta en la plataforma deWindows XP. Si las extensiones de comando están habilitadas. Similar a chcp xxx Especifica el número de la tabla de códigos. si está siendo depurado por un depurador. variable Especifica el nombre de la variable de entorno. en orden de precedencia decreciente: () !~. /STATUS Muestra la tabla de códigos seleccionada para usar con GRAFTABL. Escriba SET sin parámetros para ver las variables de entorno actuales. el comando BREAK introducirá un punto de ruptura dentro del código. SET [variable=[cadena]] Muestra. pero no tiene efecto en Windows XP. sin signo de igual ni valor. se mostrarán los valores de todas las variables cuyos prefijos coincidan con el nombre especificado como parámetro para el comando SET. Se han agregado dos modificadores nuevos al comando SET: SET /A expression SET /P variable=[promptString] El modificador /A especifica que la cadena a la derecha del signo de iguales una expresión numérica que es evaluada.operadores unarios . Por ejemplo: SET P mostrará todas las variables que empiecen con la letra 'P' El comando SET establecerá ERRORLEVEL en 1 si no se encuentra el nombre de la variable en el entorno actual.agrupar . "str2" puede ser la cadena vacía para borrar efectivamente todas las repeticiones de "str1" de la salida expandida. será necesario escribir la cadena entre comillas. El modificador /P permite establecer el valor de una variable para una líneade entrada escrita por el usuario.asignación &= ^= |= <<= >>= .bit a bit exclusivo o | . También puede especificar subcadenas para una expansión. Si la longitud no se especifica. . y usará sólo los 5 caracteres a partir del décimo primer carácter (desplazamiento 10) del resultado expandido. El operador de asignación requiere un nombre de variable de entorno a la izquierda del operador de asignación. La cadena del símbolo del sistema puede estar vacía. Si se ejecuta el comando SET /A desde la línea del comando fuera de la secuencia decomandos. %PATH:~10. De esta manera 0x12 es lo mismo que 18. se utilizará el resto del valor de la variable. .separador de expresión Si se utiliza cualquiera de los operadores lógicos o de módulo. hasta la primera aparición del fragmento de str1 que queda. se utilizará el valor cero.bit a bit = *= /= %= += -= . sustituyendo cada repetición de "str1" en el resultado expandido con "str2". Nota: la notación octal puede ser confusa: 08 y 09 no son números válidos porque 8 y 9 no son dígitos octales válidos. Cualquier cadena de la expresión que no sea numérica. y lo mismo que 022. Esto permite hacer operaciones aritméticas con los valores de variables de entorno evitando el escribir todos estos signos % para obtener sus valores. Si algún número (desplazamiento o longitud) es negativo. se tratará como variable de entorno cuyo valor se convertirá a tipo numérico antes de utilizarse. Los valores numéricos son números decimales.*/% . entonces se mostrará el valor final de la expresión.bit a bit y ^ .operadores aritméticos +.coincidirá con lo contenido en la salida expandida desde su inicio. "str1" puede empezar con un asterisco. Muestra la cadena del símbolo del sistema antes de leer la línea de entrada. a no ser que lleven el prefijo 0x delante para los números hexadecimales.5% expandirá la variable de entorno PATH. en cuyo caso. Si se especifica una variable que no está definida en el entorno actual. La sustitución de variables de entorno ha sido mejorada así: %PATH:str1=str2% expandirá la variable de entorno PATH.desplazamiento lógico & . entonces el número usado es la longitud del valor de la variable de entorno añadido al desplazamiento o longitud especificados. y 0 para los números octales.operadores aritméticos << >> . Este soporte está siempre deshabilitado de forma predeterminada. los ejemplos se pueden escribir de la siguiente manera para que funcionen como es necesario: set VAR=antes . se ha añadido compatibilidad para la expansión de la variable retardada. De un modo parecido. entonces significa que funcionó ) dado que %VAR% se sustituye al mismo tiempo en ambas instrucciones IF cuando se lee la primera instrucción IF. el cual es una instrucción compuesta. y en ese momento la variable LIST variable está vacía.-2% extraerá todo menos los 2 últimos caracteres de la variable PATH. esto ocurre porque %LIST% es expandido sólo una vez cuando la opción FOR es leída. Así el ciclo actual FOR que se está ejecutando es: for %i in (*) do set LIST= %i el cual sólo mantiene el valor LIST hasta el último archivo encontrado. Finalmente. y no cuando se ejecuta. El siguiente ejemplo demuestra el problema con la expansión de la variable inmediata: set VAR=antes if "%VAR%" == "antes" ( set VAR=después if "%VAR%" == "después" @echo Si esto se puede ver.EXE. De esta manera. IF. Si la expansión de la variable retardada está habilitada. La expansión de la variable de entorno retardada permite utilizar un carácter diferente (el signo de exclamación para expandir variables en tiempo de ejecución. pero puede habilitarse o deshabilitarse a través del modificador de línea de comandos /V a CMD. Ver CMD /? La expansión de la variable de entorno es útil para tratar con las limitaciones de la expansión actual. el siguiente ejemplo no funcionará como se espera: set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST% en esto NO generará una lista de archivos en el directorio actual. %PATH:~0. dentro de la instrucción compuesta está realmente comparando "antes" con "después" lo cuál nunca será igual. las cuales ocurren cuando una línea de texto es leída.%PATH:~-10% extraerá los 10 caracteres de la variable PATH. pues incluye lógicamente al cuerpo del IF. De nuevo. pero en su lugar establecerá la variable LIST en el último archivo encontrado. se expande al valor de NIVEL DE ERROR actual %CMDEXTVERSION% . Estos valores de variable se calculan dinámicamente cada vez que el valor de la variable se expande.se expande a la cadena del directorio actual . %TIME% .se expande a la fecha actual usando el mismo formato que el comando DATE. entonces significa que funcionó ) set LIST= for %i en (*) do set LIST=!LIST! %i echo %LIST% Si las extensiones de comando están habilitadas. %DATE% . hay varias variables dinámicas de entorno que pueden ser expandidas pero que no se muestran en la lista de variables que muestra ESTABLECER.se expande a un número decimal aleatorio entre 0 y 32767. %CMDCMDLINE% . entonces esa definición suplantará la variable dinámica abajo descrita: %CD% .se expande a la hora actual usando el mismo formato que el comando TIME.se expande al número actual de versión de las extensiones del comando del procesador. CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF] [[/S] [/C | /K] cadena] Inicia una nueva instancia del intérprete de comandos de Windows /C Ejecuta el comando especificado en cadena y luego finaliza /K Ejecuta el comando especificado en cadena pero sigue activo /S Modifica el tratamiento de cadena después de /C o /K (consultar . Si el usuario define una variable explícitamente con uno de estos nombres. %RANDOM% .se expande a la línea de comando original que invocó el Procesador de comandos.if "%VAR%" == "antes" ( set VAR=después if "!VAR!" == "después" @echo Si esto se puede ver. %ERRORLEVEL% . siguiendo la lógica siguiente para procesar caracteres comillas ("): 1. Por razones de compatibilidad. Por ejemplo. lo que viene después de la línea de comando se ejecuta como línea de comando. lo cual es diferente cuando se está dentro de un bucle FOR. /V: ON permitirá que !var! extienda la variable var en tiempo de ejecución. Tenga en cuenta que los comandos múltiples separados por el separador de comandos '&&' se aceptan como cadena si están entre comillas. Se omitirá cualquier otro tipo de modificador. La sintaxis var extiende variables en tiempo de entrada. consulte COLOR /?) /E:ON Habilita las extensiones de comando (consultar más abajo) /E:OFF Deshabilita las extensiones de comando (consultar más abajo) /F: ON Habilita los caracteres de terminación de los nombres de archivos y directorios (consultar más abajo) /F: OFF Deshabilita los caracteres de terminación de los nombres de archivos y directorios (consultar más abajo) /V: ON Habilita la extensión de variables de entorno retardada usando ! como delimitador. Se conservan las comillas del comando si se cumplen todas las condiciones siguientes: . /Y equivale a /E:OFF y /R equivale a /C. /X equivale a /E:ON.más abajo) /Q Deshabilita el eco /D Deshabilita le ejecución de los comandos de AutoRun del registro (consultar más abajo) /A Utiliza ANSI para la salida de comandos internos hacia una canalización o un archivo /U Utiliza UNICODE para la salida de comandos internos hacia una canalización o un archivo /T: fg Configura los colores de primer y segundo plano (para obtener más información. /V: OFF Deshabilita la extensión de variables de entorno retardada. Si se especifica /C o /K. siendo los caracteres especiales: &<>()@^| . buscará las variables del Registro REG_SZ/REG_EXPAND_SZ. se ejecutarán en primer lugar.EXE se inicie.hay exactamente dos caracteres comillas . cuando CMD.hay uno o más espacios en blanco entre ambas comillas . quitar ésta y también la última comilla de la línea de comandos. el comportamiento clásico es comprobar si el primer carácter es una comilla y de ser así. Puede deshabilitar las extensiones de una invocación particular usando el modificador /E:OFF.no hay caracteres especiales entre ambas comillas. Puede habilitar o deshabilitar las extensiones de todas las invocaciones de CMD. HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun y (o) HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun Las extensiones de comando están habilitadas de forma predeterminada. conservando el texto que venga después de ésta Si no se especificó /D en la línea de comandos.EXE en una máquina o en una sesión de usuario estableciendo con REGEDT32..no aparece el modificador /S .la cadena entre ambas comillas es el nombre de un archivo ejecutable 2. En caso contrario. y si alguna de ellas está presente.EXE los dos valores de REG_DWORD del registro siguientes: HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\EnableExtensions y (o) . HKEY_CURRENT_USER\Software\Microsoft\Command Processor\EnableExtensions a 0x1 o 0x0.EXE los dos valores de REG_DWORD del registro siguientes: HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\DelayedExpansion y (o) .EXE en una sesión de inicio de usuario o equipo estableciendo con REGEDT32. La configuración específica del usuario tiene preferencia respecto a la del equipo. Puede habilitar o deshabilitar la expansión de variables de entorno retardada para una llamada particular de CMD. escriba nombredelcomando /?. Puede habilitar o deshabilitar la terminación para todas las llamadas de CMD. Los modificadores de la línea de comando tienen prioridad sobre la configuración del registro Las extensiones de comando implican cambios y ampliaciones en los siguientes comandos: DEL o ERASE COLOR CD o CHDIR MD o MKDIR PROMPT PUSHD POPD SET SETLOCAL ENDLOCAL IF FOR CALL SHIFT GOTO START (también incluye cambios en la invocación de comandos externos) ASSOC FTYPE Para obtener detalles específicos. La expansión de variables de entorno retardada NO está habilitada de manera predeterminada.EXE con los modificadores /V:ON o /V:OFF. HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion a 0x1 ó 0x0. Si la terminación está habilitada con el modificador /F:ON. Se puede habilitar o deshabilitar la terminación para todas las invocaciones de CMD.EXE: HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\CompletionChar HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\PathCompletionChar y/o HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionChar HKEY_CURRENT_USER\Software\Microsoft\Command Processor\PathCompletionChar con el valor hex de un carácter de control para utilizarlo en una función particular (por ej.Los modificadores de la línea de comandos tiene precedencia sobre laconfiguración del registro. La terminación de los nombres de Archivo y Directorio NO está habilitada de forma predeterminada. Si la expansión de variables de entorno retardada está habilitada. La configuración de usuario específica tiene precedencia sobre la configuración de la máquina.EXE en una máquina y/o el inicio de sesión del usuario estableciendo cualquiera de los dos siguientes valores REG_DWORD en el registro usando REGEDT32. Se puede habilitar o deshabilitar la terminación de un nombre de archivo para una invocación particular de CMD.EXE con el modificador /F:ON o /F:OFF. La configuración específica del usuario tiene prioridad sobre la configuración del equipo. se puede utilizar el carácter de exclamación para sustituir el valor de la variable de entorno en tiempo de ejecución. 0x4 es Ctrl-D y 0x6 es Ctrl-F). los dos caracteres de control usados son Ctrl-D para la terminación del nombre del directorio y . Los modificadores de la línea de comandos tienen prioridad sobre la configuración del Registro. la lista de ruta de acceso guardada es anulada y se generará una nueva. La función de terminación. El código de terminación trata adecuadamente con nombres de archivo que contienen espacios u otros caracteres especiales colocando comillas entre la ruta de acceso que coincide. si se hace una copia de seguridad. Posteriormente. utilice el valor del espacio en blanco (0x20). se llamará a una . La única diferencia entre los dos caracteres de control es que la terminación del carácter del archivo coincide con ambos nombres del archivo y del directorio. el presionar repetidamente el mismo carácter de control se desplazará a través de la lista de las rutas de acceso que coinciden. También. Para deshabilitar una terminación de carácter determinada en el registro. Después muestra la primera ruta de acceso que coincida. Si presiona la tecla Mayús con el carácter de control se moverá a través de la lista hacia atrás. emite un sonido y no muestra nada. Si la terminación del archivo es usada en cualquier construcción de comandos de directorio (CD. le anexa un carácter comodín si no hay ninguno todavía presente y genera una lista de rutas de acceso que coincidan. Ocurrirá lo mismo si pasa de una terminación de nombre de archivo a uno de directorio. mientras que la terminación del carácter del directorio sólo coincide con los nombres del directorio. ya que no es un carácter de control válido. MD o RD) entonces se asume la terminación del directorio. desplaza el contenido de la ruta de acceso hacia la izquierda del cursor. Si no coincide ninguna ruta de acceso.Ctrl-F para la terminación del nombre de archivo. Se invoca la terminación cuando se escriben cualquiera de los dos caracteres de control. Si se edita la línea de cualquier manera y presiona el carácter de control de nuevo. A modo de ejemplo tenemos a continuación los códigos de salida de Xcopy: Código Significado 0 Los ficheros fueron copiados sin error. el texto a la derecha del cursor que fue llamado en el punto de la terminación es descartado. Muchos ficheros por lotes necesitan saber si la orden anterior cumplió su cometido correctamente: para ello utilizan la orden If errorlevel. Generalmente un código de salida 0 indica que no hubo ningún problema y un código de salida superior hace referencia a diferentes errores.terminación dentro de la misma línea. 5 Ocurrió un error de escritura de disco. @echo off rem Programa: COPIA-AB. se introdujo un nombre de unidad no válida o se utilizó una sintaxis incorrecta en la línea de órdenes. Es muy importante recordar que la orden se ejecutará si el código de salida es igual o superior al especificado detrás de ERRORLEVEL. 2 El usuario presionó Ctrl+Pausa para suspender el proceso de Xcopy. Vamos a crear un fichero por lotes para copiar los ficheros de la unidad A: a la B: e informe del resultado de la copia.`~ IF ERRORLEVEL Cada orden externa de ms-dos genera un código de salida a su término indicando si pudo realizarse satisfactoriamente.!'+. 1 No se encontraron ficheros para copiar. 4 Ocurrió un error de inicio.BAT . No hay suficiente memoria o espacio en el disco. Los caracteres especiales que requieren comillas son: &()[]{}^=. /S Hace distinción entre mayúsculas y minúsculas. Si se ha producido algún error el código será 1 o superior y entonces. el programa se desvía hasta la etiqueta :Error. Para cumplirse exclusivamente si el código de salida es 5 -por ejemplopodemos usar lo siguiente: if errorlevel 5 if not errorlevel 6 dir Esta compleja línea se traduce así: «Si el código de salida es 5 o superior pero inferior a 6 ejecutar Dir». /T:opción. el código de salida es 0. dependiendo de la opción elegida.segs Toma la opción indicada si no se pulsa ninguna otra tecla en los segundos especificados. Si no se especifica este parámetro se toman como la misma opción. muestra el mensaje y finaliza. Si no se especifica este parámetro se asumen las opciones por defecto (SN). .xcopy a:\ b:\ if errorlevel 1 goto Error if errorlevel 0 echo ¡La copia fue correcta! goto Final :Error echo Se produjo un error durante la copia :Final En primer lugar. Si el usuario pulsa la primera de las opciones. Si la copia fue satisfactoria. Xcopy intenta realizar la copia de ficheros y devolverá un código de salida. es decir. En muchas ocasiones puede ser fuente de complicaciones que If errorlevel número se cumpla si el número es igual o mayor. /N No muestra las opciones admitidas detrás del mensaje. si pulsa la segunda opción. La segunda línea If mostrará el mensaje de éxito. termina el proceso. Choice devolverá un código de salida 1. Su sintaxis es: CHOICE [mensaje] [/C:opciones] [/N] [/S] [/T:opción. Choice devuelve el código 2 y así sucesivamente. La orden CHOICE Permite escoger una opción entre varias y. mensaje Contiene el mensaje mostrado al usuario pidiendo que introduzca una de las opciones admitidas. si el código es 5 ejecutar Dir. saltando después a la etiqueta :Final y como no hay más líneas. devuelve un código de salida.segundos] /C:opciones Especifica las opciones posibles. El programa DEMO.BAT podemos mejorarlo sensiblemente si cambiamos las órdenes Pause por órdenes Choice. @echo off rem Programa: DEMOB.BAT echo ******************************************** echo ** Este programa copia todos los ficheros ** echo ** de la unidad A: al directorio actual ** echo ******************************************** choice ¿Desea continuar? if errorlevel 2 goto Final :Proceso copy a:\ . choice Para continuar con otro disquete pulse C y para finalizar, F /C:FC if errorlevel 2 goto proceso :Final En la primera orden Choice se toman las opciones por defecto S y N. `S' corresponde a un código de salida 1 y `N' a un código 2. En la segunda orden Choice se toman las opciones F y C. `F' corresponde a un código 1 y `C' a un código 2. Con la orden Choice y de una forma muy sencilla podemos crear menús con diferentes opciones: @echo off rem Programa: UTIL.BAT :Menu cls echo UTILIDADES DE MS-DOS echo -------------------echo. echo A. Anti-Virus echo B. Backup echo D. Defragmentar echo E. Editor echo S. Salir echo. choice ¿Qué utilidad desea comenzar? /c:abdes /n /t:s,15 if errorlevel 5 goto Salir if errorlevel 4 goto Editor if errorlevel 3 goto Defrag if errorlevel 2 goto Backup if errorlevel 1 goto Anti if errorlevel 0 goto Menu :Anti MSAV goto Menu :Backup MSBACKUP goto Menu :Defrag DEFRAG goto Menu :Editor EDIT goto Menu :Salir echo. Observe la orden Choice: el modificador /C indica las opciones admitidas. Si se pulsa la `A' se generará un código de salida 1 y así sucesivamente hasta la `S' que corresponde a un código 5. Gracias al modificador /N Choice no muestra las teclas admitidas detrás del mensaje. El modificador /T toma como opción por defecto la `S' si pasan 15 segundos sin pulsar ninguna tecla. Observe, asimismo, cómo se ha comenzado en las líneas If por el errorlevel más alto: así se evitan conflictos. El código de salida 0 se obtiene si el usuario responde con Ctrl+Pausa al mensaje de Choice Ejemplo de un proceso batch Lo que voy a realizar aqui, es un proceso batch que os permita entender mejor la teoria que explique en la entrada de "Curso basico de MS-DOS". Este proceso lo que hace es crear un menu principal que contiene los siguientes puntos: • • • Aplicaciones Utilidades Fin Dentro de estos hay submenus que llevan a ordenes como la de copiar un archivo etc... Este es el proceso: @echo off echo MENU PRINCIPAL echo 1-Aplicaciones echo 2-Utilidades echo 3-Fin echo -------------------------------------choice /c 123 /m "Elija una opcion" @if errorlevel 3 goto :fin @if errorlevel 2 goto :utilidades @if errorlevel 1 goto :aplicaciones :aplicaciones cls echo A.-Memoria echo B.-Fecha echo C.-Menu principal choice /c ABC /m "Elija una opcion" cls @if errorlevel 3 Examen.bat @if errorlevel 2 goto :fecha @if errorlevel 1 goto :memoria :memoria cls ver pause goto :menu :fecha cls date 01-01-2011 date /t pause goto :menu :utilidades cls echo A.-util1 echo B.-util2 echo C.-copiar echo D.-Menu principal choice /c ABCD /m "Elija una opcion" @if errorlevel 4 goto :menu @if errorlevel 3 goto :copiar @if errorlevel 2 goto :util2 @if errorlevel 1 goto :util1 :util1 cls dir c:\utilidades /a:a pause goto :menu :util2 *" pause goto :menu :copiar cls copy c:\prueba.txt pause goto :menu :fin exit FINAL DEL PROCESO .txt c:\asi1\texto1.cls dir c:\ "asi1.