Un archivo por lotes es un archivo de secuencia de comandos en DOS , OS/2 y Microsoft Windows . Consiste en una serie de comandos que debe ejecutar el intérprete de línea de comandos , almacenados en un archivo de texto sin formato . Un archivo por lotes puede contener cualquier comando que el intérprete acepte de forma interactiva y utilizar construcciones que permitan la ramificación condicional y el bucle dentro del archivo por lotes, como IF
, FOR
, y GOTO
etiquetas . El término "lote" proviene de procesamiento por lotes , que significa "ejecución no interactiva", aunque un archivo por lotes podría no procesar un lote de múltiples datos.
De manera similar al lenguaje de control de tareas (JCL), DCL y otros sistemas en sistemas mainframe y minicomputadoras, se agregaron archivos por lotes para facilitar el trabajo requerido para ciertas tareas regulares al permitir que el usuario configure un script para automatizarlas. Cuando se ejecuta un archivo por lotes, el programa de shell (generalmente COMMAND.COM o cmd.exe ) lee el archivo y ejecuta sus comandos, normalmente línea por línea. [1] Los sistemas operativos tipo Unix , como Linux , tienen un tipo de archivo similar, pero más flexible, llamado script de shell . [2]
La extensión de nombre de archivo .bat se utiliza en DOS y Windows. Windows NT y OS/2 también agregaron .cmd . Los archivos por lotes para otros entornos pueden tener extensiones diferentes, por ejemplo, .btm en los shells relacionados con 4DOS , 4OS2 y 4NT .
El manejo detallado de los archivos por lotes ha cambiado significativamente entre versiones. Algunos de los detalles de este artículo se aplican a todos los archivos por lotes, mientras que otros se aplican solo a ciertas versiones.
En MS-DOS , se puede iniciar un archivo por lotes desde la interfaz de línea de comandos escribiendo su nombre, seguido de los parámetros necesarios y presionando la ↵ Entertecla . Cuando se carga DOS, el archivo AUTOEXEC.BAT , si está presente, se ejecuta automáticamente, por lo que cualquier comando que se deba ejecutar para configurar el entorno DOS se puede colocar en este archivo. Los usuarios de computadoras harían que el archivo AUTOEXEC.BAT configure la fecha y la hora del sistema, inicialice el entorno DOS, cargue cualquier programa residente o controlador de dispositivo o inicialice las conexiones y asignaciones de red.
Una extensión de nombre de archivo .bat identifica un archivo que contiene comandos que son ejecutados por el intérprete de comandos COMMAND.COM línea por línea, como si fuera una lista de comandos ingresados manualmente, con algunos comandos adicionales específicos del archivo por lotes para la funcionalidad de programación básica, incluido un GOTO
comando para cambiar el flujo de ejecución de la línea.
Microsoft Windows se introdujo en 1985 como una interfaz gráfica de usuario (GUI) superpuesta a los sistemas operativos basados en texto y fue diseñado para ejecutarse en DOS. Para iniciarlo, WIN
se utilizaba el comando, que podía añadirse al final del archivo AUTOEXEC.BAT para permitir la carga automática de Windows. En las versiones anteriores, se podía ejecutar un archivo de tipo .bat desde Windows en el símbolo del sistema de MS-DOS. Windows 3.1x y versiones anteriores, así como Windows 9x, invocaban COMMAND.COM para ejecutar archivos por lotes.
El sistema operativo IBM OS/2 admitía archivos por lotes de estilo DOS. También incluía una versión de REXX , un lenguaje de scripts de archivos por lotes más avanzado . IBM y Microsoft comenzaron a desarrollar este sistema, pero durante su construcción se separaron tras una disputa; como resultado de esto, IBM se refirió a su consola tipo DOS sin mencionar a Microsoft, llamándola simplemente DOS, aunque aparentemente esto no hizo ninguna diferencia con respecto a la forma en que funcionaban los archivos por lotes desde COMMAND.COM.
El intérprete de archivos por lotes de OS/2 también admite un comando EXTPROC. Este pasa el archivo por lotes al programa nombrado en el archivo EXTPROC como un archivo de datos. El programa nombrado puede ser un archivo de script; esto es similar al mecanismo #! utilizado por los sistemas operativos tipo Unix .
A diferencia de Windows 98 y versiones anteriores, la familia de sistemas operativos Windows NT no depende de MS-DOS. Windows NT introdujo un intérprete de comandos de 32 bits mejorado ( cmd.exe ) que podía ejecutar scripts con la extensión .CMD o .BAT. Cmd.exe agregó comandos adicionales e implementó los existentes de una manera ligeramente diferente, de modo que el mismo archivo por lotes (con una extensión diferente) podría funcionar de manera diferente con cmd.exe y COMMAND.COM. En la mayoría de los casos, el funcionamiento es idéntico si no se utilizan los pocos comandos no compatibles. Las extensiones de cmd.exe a COMMAND.COM se pueden deshabilitar para lograr compatibilidad.
Microsoft lanzó una versión de cmd.exe para Windows 9x y ME llamada WIN95CMD para permitir a los usuarios de versiones anteriores de Windows utilizar ciertos archivos por lotes de estilo cmd.exe.
A partir de Windows 8 [actualizar], cmd.exe es el intérprete de comandos normal para archivos por lotes; el antiguo COMMAND.COM también se puede ejecutar en versiones de 32 bits de Windows capaces de ejecutar programas de 16 bits. [nb 1]
append
, dpath
, ftype
, set
, path
, assoc
y prompt
, cuando se ejecutan desde un archivo .bat, modifican el valor de la errorlevel
variable solo en caso de error, mientras que desde un archivo .cmd, afectarían a errorlevel incluso si regresaran sin ningún error. [3] También lo utiliza el sistema operativo/2 de IBM para archivos por lotes.COMMAND.COM y cmd.exe admiten variables especiales ( %0
, %1
a %9
) para hacer referencia a la ruta y el nombre del trabajo por lotes y los primeros nueve parámetros de llamada desde dentro del trabajo por lotes, consulte también SHIFT. Los parámetros inexistentes se reemplazan por una cadena de longitud cero. Se pueden usar de manera similar a las variables de entorno , pero no se almacenan en el entorno. Microsoft e IBM se refieren a estas variables como parámetros de reemplazo o parámetros reemplazables , mientras que Digital Research, Novell y Caldera establecieron el término variables de reemplazo [5] para ellas. JP Software las llama parámetros de archivo por lotes . [6]
Este archivo por lotes de ejemplo muestra Hello World!
, solicita y espera que el usuario presione una tecla y luego finaliza. (Nota: No importa si los comandos están en minúsculas o mayúsculas a menos que se trabaje con variables)
@ ECHO OFF ECHO ¡ Hola mundo! PAUSA
Para ejecutar el archivo, éste debe guardarse con el sufijo de extensión de nombre de archivo .bat (o .cmd para sistemas operativos tipo Windows NT) en formato de texto simple, normalmente creado mediante un editor de texto como el Bloc de notas de Microsoft o un procesador de textos que trabaje en modo de texto simple.
Al ejecutarlo se muestra lo siguiente:
¡Hola Mundo!Presione cualquier tecla para continuar...
El intérprete ejecuta cada línea por turno, comenzando por la primera. El @
símbolo al comienzo de cualquier línea evita que el indicador muestre ese comando a medida que se ejecuta. El comando ECHO OFF
apaga el indicador de forma permanente o hasta que se vuelva a encender. El símbolo combinado @ECHO OFF
suele ser, como en este caso, la primera línea de un archivo por lotes, lo que evita que se muestren los comandos, incluido él mismo. A continuación, se ejecuta la siguiente línea y el ECHO Hello World!
comando genera Hello World!
. Se ejecuta la siguiente línea y el PAUSE
comando muestra Press any key to continue . . .
y pausa la ejecución del script. Después de presionar una tecla, el script finaliza, ya que no hay más comandos. En Windows, si el script se ejecuta desde una ventana del indicador de comandos que ya se está ejecutando , la ventana permanece abierta en el indicador como en MS-DOS; de lo contrario, la ventana se cierra al finalizar.
Las expansiones de variables se sustituyen textualmente en el comando y, por lo tanto, las variables que no contienen nada simplemente desaparecen de la sintaxis y las variables que contienen espacios se convierten en múltiples tokens. Esto puede provocar errores de sintaxis o fallos.
Por ejemplo, si %foo% está vacío, esta declaración:
SI %foo% == bar ECHO Igual
analiza como la construcción errónea:
SI ==barra ECHO Igual
De manera similar, si %foo%
contiene abc def
, se produce un error de sintaxis diferente:
SI abc def == bar ECHO Igual
La forma habitual de evitar este problema es encerrar las expansiones de variables entre comillas para que una variable vacía se expanda en la expresión válida IF ""=="bar"
en lugar de en la no válida IF ==bar
. El texto que se compara con la variable también debe estar entre comillas, ya que las comillas no son una sintaxis delimitadora especial; estos caracteres se representan a sí mismos.
SI " %foo% " == "bar" ECHO Igual
La expansión retardada !VARIABLE! disponible en Windows 2000 y versiones posteriores se puede utilizar para evitar estos errores sintácticos. En este caso, las variables nulas o de varias palabras no fallan sintácticamente porque el valor se expande después de analizar el comando IF:
SI !foo! == bar ECHO Igual
Otra diferencia en Windows 2000 o versiones posteriores es que no se sustituye una variable vacía (indefinida). Como se describió en los ejemplos anteriores, el comportamiento anterior del intérprete por lotes habría dado como resultado una cadena vacía. Ejemplo:
C:\> establecer MiVar = C:\> echo %MiVar% %MiVar%C:\> if " %MyVar% " == "" ( echo MyVar no está definido ) else ( echo MyVar es %MyVar% ) MyVar es %MyVar%
Los intérpretes de lotes anteriores a Windows 2000 habrían mostrado el resultado MyVar is not defined
.
A diferencia de los procesos Unix/POSIX, que reciben sus argumentos de línea de comandos ya divididos por el shell en una matriz de cadenas, un proceso de Windows recibe toda la línea de comandos como una sola cadena, a través de la función API GetCommandLine. Como resultado, cada aplicación de Windows puede implementar su propio analizador para dividir toda la línea de comandos en argumentos. Muchas aplicaciones y herramientas de línea de comandos han desarrollado su propia sintaxis para hacer eso, por lo que no existe una convención única para entrecomillar o escapar metacaracteres en las líneas de comandos de Windows.
cmd.exe
y wscript.exe
, utilizan sus propias reglas. [8]Cuando una cadena contiene comillas y se debe insertar en otra línea de texto que también debe estar entre comillas, se requiere especial atención al mecanismo de comillas:
C:\> set foo = "esta cadena está entre comillas"C:\> echo "test 1 %foo% " "test 1 "esta cadena está entre comillas""C:\> eventcreate /T Advertencia /ID 1 /L Sistema /SO "Origen" /D "Ejemplo: %foo% " ERROR: Argumento/Opción no válidos: 'string'. Escriba "EVENTCREATE /?" para su uso.
En Windows 2000 y versiones posteriores, la solución es reemplazar cada aparición de un carácter de comillas dentro de un valor por una serie de tres caracteres de comillas:
C:\> set foo = "esta cadena está entre comillas"C:\> establecer foo = %foo:"="""%C:\> echo "test 1 %foo% " "test 1 """esta cadena está entre comillas""""C:\> eventcreate /T Warning /ID 1 /L System /SO "Source" /D "Ejemplo: %foo% " ÉXITO: Se crea un evento de tipo 'Advertencia' en el registro/fuente 'Fuente'.
Algunos caracteres, como |
los caracteres de barra vertical ( ), tienen un significado especial en la línea de comandos. No se pueden imprimir como texto con el comando ECHO a menos que se los escape con el símbolo de intercalación ^:
C:\> echo foo | bar 'bar' no se reconoce como un comando interno o externo, un programa ejecutable o un archivo por lotes.C:\> echo foo ^| bar foo | bar
Sin embargo, el escape no funciona como se espera cuando se inserta el carácter escapado en una variable de entorno. La variable termina conteniendo un comando de canalización activo cuando simplemente se repite. Es necesario escapar tanto el cursor como el carácter escapado para que el carácter se muestre como texto en la variable:
C:\> set foo = bar | baz 'baz' no se reconoce como un comando interno o externo, un programa ejecutable o un archivo por lotes.C:\> set foo = bar ^| baz C:\> echo %foo% 'baz' no se reconoce como un comando interno o externo, un programa ejecutable o un archivo por lotes.C:\> establecer foo = barra ^^^| baz C:\> echo %foo% barra | baz
La expansión retardada disponible con o con en Windows 2000 y versiones posteriores se puede utilizar para mostrar caracteres especiales almacenados en variables de entorno porque el valor de la variable se expande después de analizar el comando:
C:\> cmd /V:ON Microsoft Windows [Versión 6.1.7601] Copyright (c) 2009 Microsoft Corporation. Todos los derechos reservados.C:\> establecer foo = barra ^| baz C:\> eco !foo! barra | baz
Hasta que se introdujo el comando TIMEOUT con Windows Vista, no había una manera sencilla de implementar una pausa temporizada, ya que el comando PAUSE detiene la actividad del script indefinidamente hasta que se presiona alguna tecla.
Se podían encontrar muchas soluciones alternativas [10] , pero por lo general sólo funcionaban en algunos entornos: el CHOICE
comando no estaba disponible en versiones anteriores de DOS, PING
sólo estaba disponible si se instalaba TCP/IP, etc. No había ninguna solución disponible de Microsoft, pero se podían instalar varios programas de utilidad pequeños desde otras fuentes. Un ejemplo comercial sería el comando Norton Utilities Batch Enhancer (BE) de 1988, donde BE DELAY 18
esperaría 1 segundo, o el comando gratuito WAIT.COM de 94 bytes [11] donde WAIT 5
esperaría 5 segundos y luego devolvería el control al script. La mayoría de estos programas son archivos .COM de 16 bits, por lo que son incompatibles con Windows de 64 bits.
Normalmente, todo texto impreso tiene automáticamente los caracteres de control para retorno de carro (CR) y avance de línea (LF) añadidos al final de cada línea.
@ echo foo @ echo bar
C : \> batchtest.bat foobar
No importa si los dos comandos echo comparten la misma línea de comando; los códigos CR/LF se insertan para dividir la salida en líneas separadas:
C:\> @ echo Mensaje 1 &@ echo Mensaje 2 Mensaje 1 Mensaje 2
Un truco descubierto con Windows 2000 y versiones posteriores es utilizar el mensaje especial de entrada para generar texto sin que CR/LF aparezca después del texto. En este ejemplo, CR/LF no aparece después del Mensaje 1, pero sí después de la Línea 2 y la Línea 3:
@ echo off set /p = "Mensaje 1" < nul echo Mensaje 2 echo Mensaje 3
C:\> batchtest2.bat Mensaje 1Mensaje 2 Mensaje 3
Esto se puede utilizar para enviar datos a un archivo de texto sin CR/LF adjunto al final:
C:\> set /p = "Mensaje 1" < nul > datos.txt C:\> set /p = "Mensaje 2" < nul >> datos.txt C:\> set /p = "Mensaje 3" < nul >> datos.txt C:\> type datos.txt Mensaje 1Mensaje 2Mensaje 3
Sin embargo, no hay manera de inyectar esta salida del indicador CR/LF eliminada directamente en una variable de entorno.
No es posible tener un símbolo del sistema que utilice una ruta UNC como directorio de trabajo actual; por ejemplo\\server\share\directory\
El símbolo del sistema requiere el uso de letras de unidad para asignar un directorio de trabajo, lo que dificulta la ejecución de archivos por lotes complejos almacenados en un recurso compartido UNC del servidor. Si bien un archivo por lotes se puede ejecutar desde una ruta de archivo UNC, el directorio de trabajo predeterminado es C:\Windows\System32\
.
En Windows 2000 y versiones posteriores, una solución alternativa es utilizar el comando PUSHD
and POPDcon extensiones de comando. [nb 2]
Si no están habilitadas de forma predeterminada, las extensiones de comando se pueden habilitar temporalmente utilizando el /E:ON
interruptor para el intérprete de comandos.
Entonces, para ejecutar un archivo por lotes en un recurso compartido UNC, asignar una letra de unidad temporal al recurso compartido UNC y usar el recurso compartido UNC como directorio de trabajo del archivo por lotes, se puede construir un acceso directo de Windows que se parece al siguiente:
Se ignora el atributo de directorio de trabajo de este acceso directo.
Esto también resuelve un problema relacionado con el Control de cuentas de usuario (UAC) en Windows Vista y versiones posteriores. Cuando un administrador inicia sesión y el UAC está habilitado, e intenta ejecutar un archivo por lotes como administrador desde una letra de unidad de red, utilizando el menú contextual del archivo con el botón derecho, la operación fallará inesperadamente. Esto se debe a que el contexto de cuenta privilegiada de UAC elevada no tiene asignaciones de letras de unidad de red y no es posible asignar letras de unidad para el contexto elevado a través del shell del Explorador o los scripts de inicio de sesión. Sin embargo, al crear un acceso directo al archivo por lotes utilizando la construcción PUSHD
/ anterior POPD
y utilizando el acceso directo para ejecutar el archivo por lotes como administrador, se creará y eliminará la letra de unidad temporal en el contexto de cuenta elevada y el archivo por lotes funcionará correctamente.
La siguiente sintaxis se expande correctamente a la ruta del script por lotes actual.
%~dp0
Las rutas UNC predeterminadas están desactivadas de forma predeterminada, ya que solían bloquear programas más antiguos. [12]
El valor de registro Dword DisableUNCCheck
en HKEY_CURRENT_USER\Software\Microsoft\Command Processor
[12] permite que el directorio predeterminado sea UNC. CD
El comando se negará a cambiar, pero colocará una ruta UNC en el Directorio predeterminado en un acceso directo a Cmd o usando el comando Inicio. ( C$
share es para administradores).
Los archivos por lotes utilizan un conjunto de caracteres OEM, tal como lo define la computadora, por ejemplo, la página de códigos 437. Las partes que no son ASCII de estos son incompatibles con los conjuntos de caracteres Unicode o Windows que se usan en Windows, por lo que se debe tener cuidado. [13] Los nombres de archivo que no están en inglés solo funcionan si se ingresan a través de un editor compatible con el conjunto de caracteres DOS. Los nombres de archivo con caracteres fuera de este conjunto no funcionan en archivos por lotes.
Para obtener un símbolo del sistema con Unicode en lugar de la página de códigos 437 o similar, se puede utilizar el cmd /U
comando . En un símbolo del sistema de este tipo, funcionará un archivo por lotes con nombres de archivo Unicode. También se puede utilizar cmd /U
para ejecutar directamente comandos con Unicode como conjunto de caracteres. Por ejemplo, cmd /U /C dir > files.txt
crea un archivo que contiene una lista de directorios con caracteres de Windows correctos, en la codificación UTF-16 LE.
Al igual que con cualquier otro lenguaje de programación, los archivos por lotes pueden usarse de forma maliciosa. Se crean fácilmente troyanos simples y bombas de bifurcación , y los archivos por lotes pueden realizar una forma de envenenamiento de DNS modificando el archivo hosts . Los virus por lotes son posibles y también pueden propagarse a través de unidades flash USB utilizando la capacidad de ejecución automática de Windows . [14]
El siguiente comando en un archivo por lotes eliminará todos los datos en el directorio (carpeta) actual, sin solicitar primero confirmación:
del /Q *.*
Estos tres comandos son una simple bomba de bifurcación que se replicará continuamente para agotar los recursos disponibles del sistema, ralentizando o bloqueando el sistema:
: TOP inicio "" %0 ir a TOP
El procesador de comandos cmd.exe que interpreta los archivos .cmd es compatible con todas las versiones de 32 bits de Windows hasta Windows 10 y con las versiones de 64 bits de Windows hasta Windows 11. COMMAND.EXE, que interpreta los archivos .BAT, era compatible con todas las versiones de 16 y 32 bits hasta al menos Windows 10. [nb 3]
Existen otros lenguajes de programación más modernos y potentes disponibles para Windows. Sin embargo, es necesario instalar el intérprete de lenguaje de programación antes de poder usarlos:
Los archivos de script se ejecutan si se introduce el nombre del archivo sin extensión. Existen reglas de precedencia que rigen la interpretación de, por ejemplo, DoThis
si existe DoThis.com
, DoThis.exe
, DoThis.bat
, DoThis.cmd
, etc.; de forma predeterminada, DoThis.com
tiene la máxima prioridad. Este orden predeterminado se puede modificar en los sistemas operativos más nuevos mediante la variable de entorno PATHEXT configurable por el usuario .
COMMAND.COM
en el símbolo del sistema de Windows 7 de 32 bits.Dos comillas dobles consecutivas dentro de una región inQuotes deberían dar como resultado una comilla doble literal (el analizador se deja en la región inQuotes). Este comportamiento no forma parte de la especificación de code:ParseArgumentsIntoList, pero es compatible con CRT y .NET Framework.