Un archivo por lotes es un archivo de secuencia de comandos en DOS , OS/2 y Microsoft Windows . Consta de una serie de comandos que debe ejecutar el intérprete de línea de comandos , almacenados en un archivo de texto plano . Un archivo por lotes puede contener cualquier comando que el intérprete acepte de forma interactiva y utilizar construcciones que permitan bifurcaciones y bucles condicionales dentro del archivo por lotes, como IF
, FOR
y GOTO
etiquetas . El término "lote" proviene del procesamiento por lotes , que significa "ejecución no interactiva", aunque es posible que un archivo por lotes no procese un lote de datos múltiples.
Al igual que Job Control Language (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 al usuario configurar un script para automatizarlas. Cuando se ejecuta un archivo por lotes, el programa shell (normalmente 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 diferentes extensiones, por ejemplo, .btm en shells relacionados con 4DOS , 4OS2 y 4NT .
El manejo detallado de 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 detalles se aplican solo a determinadas 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 , cuando está presente, se ejecuta automáticamente, por lo que cualquier comando que deba ejecutarse para configurar el entorno DOS se puede colocar en este archivo. Los usuarios de computadoras harían que el archivo AUTOEXEC.BAT configurara la fecha y hora del sistema, inicializara el entorno DOS, cargara cualquier programa residente o controlador de dispositivo, o inicializara conexiones y asignaciones de red.
Una extensión de nombre de archivo .bat identifica un archivo que contiene comandos 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 de archivos por lotes para la funcionalidad de programación básica. incluyendo un GOTO
comando para cambiar el flujo de ejecución de la línea.
Microsoft Windows se introdujo en 1985 como una superposición basada en una interfaz gráfica de usuario (GUI) en sistemas operativos basados en texto y fue diseñado para ejecutarse en DOS. Para iniciarlo WIN
se utilizó el comando que se podía agregar 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 MS-DOS. Windows 3.1xy 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 estilo DOS. También incluía una versión de REXX , un lenguaje de programación de archivos por lotes más avanzado . IBM y Microsoft comenzaron a desarrollar este sistema, pero durante su construcción se separaron después de una disputa; Como resultado de esto, IBM se refirió a su consola tipo DOS sin mencionar a Microsoft, nombrándola simplemente DOS, aunque esto aparentemente 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. Esto 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 mejorado de 32 bits ( 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 diferente extensión) 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 desactivar por motivos de 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 COMMAND.COM anterior también se puede ejecutar en versiones de Windows de 32 bits capaces de ejecutar programas de 16 bits. [nota 1]
append
, dpath
, ftype
, set
, path
y , cuando se ejecutan desde un archivo .bat, alteran el valor de la variable solo en caso de error, mientras que desde dentro de un archivo .cmd, afectarían el nivel de error incluso cuando se regresa sin un error. [3] También lo utiliza OS/2 de IBM para archivos por lotes.assoc
prompt
errorlevel
COMMAND.COM y cmd.exe admiten variables especiales ( %0
, %1
hasta %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 utilizar de forma 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 para ellos el término variables de reemplazo [5] . JP Software los llama parámetros de archivos por lotes . [6]
Este archivo por lotes de ejemplo muestra Hello World!
, solicita y espera a 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 APAGADO ECHO ¡Hola mundo! PAUSA
Para ejecutar el archivo, debe guardarse con el sufijo de extensión de nombre de archivo .bat (o .cmd para sistemas operativos de tipo Windows NT) en formato de texto sin formato, generalmente creado usando un editor de texto como Microsoft Notepad o un procesador de textos que funcione en modo texto plano.
Cuando se ejecuta, se muestra lo siguiente:
¡Hola Mundo!Pulse 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 mensaje muestre ese comando mientras se ejecuta. El comando ECHO OFF
desactiva el mensaje de forma permanente o hasta que se vuelva a activar. El combinado @ECHO OFF
suele ser, como aquí, la primera línea de un archivo por lotes, lo que impide que se muestre cualquier comando, incluido el mismo. Luego 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 símbolo del sistema que ya se está ejecutando , la ventana permanece abierta en el símbolo del sistema 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 o errores de sintaxis.
Por ejemplo, si %foo% está vacío, esta declaración:
IF %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 a la expresión válida IF ""=="bar"
en lugar de a la inválida IF ==bar
. El texto que se compara con la variable también debe estar entre comillas, porque las comillas no son una sintaxis delimitadora especial; Estos personajes se representan a sí mismos.
IF " %foo% " == "barra" ECHO Igual
El !VARIABLE! retrasado Se puede utilizar la expansión disponible en Windows 2000 y posteriores 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! == barra ECHO Igual
Otra diferencia en Windows 2000 o superior es que no se sustituye una variable vacía (indefinida). Como se describe en 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 por lotes anteriores a Windows 2000 habrían mostrado resultados 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 serie de cadenas, un proceso de Windows recibe la línea de comandos completa 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 comando en argumentos. Muchas aplicaciones y herramientas de línea de comandos han desarrollado su propia sintaxis para hacer esto, por lo que no existe una convención única para citar o escapar metacaracteres en las líneas de comando de Windows.
cmd.exe
y wscript.exe
, utilizan sus propias reglas. [8]Cuando una cadena contiene comillas y debe insertarse 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 "prueba 1 %foo% " "prueba 1 "esta cadena está entre comillas""C:\> eventcreate /T Advertencia /ID 1 /L Sistema /SO "Fuente" /D "Ejemplo: %foo% " ERROR: Argumento/Opción no válida - 'cadena'. 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 "prueba 1 %foo% " "prueba 1 """esta cadena está entre comillas""""C:\> eventcreate /T Advertencia /ID 1 /L Sistema /SO "Fuente" /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 comando. No se pueden imprimir como texto usando el comando ECHO a menos que se escape usando el símbolo de intercalación ^:
C:\> eco foo | bar 'bar' no se reconoce como un comando interno o externo, programa ejecutable o archivo por lotes.C:\> eco foo ^| barra de foo | bar
Sin embargo, el escape no funciona como se esperaba al insertar el carácter de escape en una variable de entorno. La variable termina conteniendo un comando de canalización activa cuando simplemente se repite. Es necesario escapar tanto del símbolo de intercalación como del carácter de escape para que el carácter se muestre como texto en la variable:
C:\> establecer foo = barra | baz 'baz' no se reconoce como un comando interno o externo, programa ejecutable o archivo por lotes.C:\> establecer foo = barra ^| baz C:\> echo %foo% 'baz' no se reconoce como un comando interno o externo, programa ejecutable o archivo por lotes.C:\> establecer foo = barra ^^^| baz C:\> echo %foo% barra | baz
La expansión retrasada disponible con o con en Windows 2000 y versiones posteriores se puede usar 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. Reservados todos los derechos.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 fácil de implementar una pausa programada, ya que el comando PAUSE detiene la actividad del script indefinidamente hasta que se presiona cualquier tecla.
Eran posibles muchas soluciones, [10] pero generalmente sólo funcionaban en algunos entornos: el CHOICE
comando no estaba disponible en versiones anteriores de DOS, PING
sólo estaba disponible si TCP/IP estaba instalado, etc. Microsoft no ofrecía ninguna solución, pero se podían instalar varios pequeños programas de utilidad desde otras fuentes. Un ejemplo comercial sería el comando Norton Utilities Batch EnhancerBE DELAY 18
(BE) de 1988, donde esperaría 1 segundo, o el WAIT.COM [11] gratuito de 94 bytes 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 el texto impreso tiene automáticamente los caracteres de control de retorno de carro (CR) y avance de línea (LF) añadidos al final de cada línea.
@ eco foo @ barra de eco
C:\> barra foo de prueba por lotes.bat
No importa si los dos comandos de eco 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 posteriores es utilizar el mensaje especial de entrada para generar texto sin CR/LF detrás del texto. En este ejemplo, el CR/LF no sigue el Mensaje 1, pero sí sigue la Línea 2 y la Línea 3:
@ echo off set /p = "Mensaje 1" < nul echo Mensaje 2 echo Mensaje 3
C:\> lotetest2.bat Mensaje 1 Mensaje 2 Mensaje 3
Esto se puede utilizar para enviar datos a un archivo de texto sin CR/LF añadido al final:
C:\> set /p = "Mensaje 1" < nul > data.txt C:\> set /p = "Mensaje 2" < nul >> data.txt C:\> set /p = "Mensaje 3" < nul >> datos.txt C:\> escriba datos.txt Mensaje 1 Mensaje 2 Mensaje 3
Sin embargo, no hay forma de inyectar esta salida del mensaje 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; p.ej\\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
y POPDcon extensiones de comando. [nota 2]
Si no están habilitadas de forma predeterminada, las extensiones de comando se pueden habilitar temporalmente usando el /E:ON
interruptor del 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 ve así:
Se ignora el atributo del 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 UAC está habilitado, e intenta ejecutar un archivo por lotes como administrador desde una letra de unidad de red, usando el menú contextual del archivo al hacer clic con el botón derecho, la operación fallará inesperadamente. Esto se debe a que el contexto de cuenta privilegiada de UAC elevado no tiene asignaciones de letras de unidad de red y no es posible asignar letras de unidad para el contexto elevado mediante el shell del Explorador o los scripts de inicio de sesión. Sin embargo, al crear un acceso directo al archivo por lotes usando la construcción PUSHD
/ anterior POPD
y usar el acceso directo para ejecutar el archivo por lotes como administrador, la letra de unidad temporal se creará y eliminará en el contexto de la 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 del 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$
compartir es para administradores).
Los archivos por lotes utilizan un juego de caracteres OEM, según lo definido por la computadora, por ejemplo, página de códigos 437 . Las partes que no son ASCII son incompatibles con los conjuntos de caracteres Unicode o Windows que de otro modo se usarían en Windows, por lo que se debe tener cuidado. [13] Los nombres de archivos que no están en inglés funcionan sólo si se ingresan a través de un editor compatible con el juego de caracteres de DOS. Los nombres de archivos 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 usar el cmd /U
comando. En dicho símbolo del sistema, funcionará un archivo por lotes con nombres de archivo Unicode. También se puede utilizar cmd /U
para ejecutar comandos directamente con Unicode como juego de caracteres. Por ejemplo, cmd /U /C dir > files.txt
crea un archivo que contiene una lista de directorios con caracteres correctos de Windows, en codificación UTF-16 LE.
Como ocurre con cualquier otro lenguaje de programación, los archivos por lotes se pueden utilizar de forma maliciosa. Se crean fácilmente troyanos y bombas de bifurcación simples , y los archivos por lotes pueden provocar una forma de envenenamiento de DNS al modificar el archivo de 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 pedir confirmación primero:
del /Q *.*
Estos tres comandos son una simple bomba de bifurcación que se replicará continuamente para agotar los recursos disponibles del sistema, ralentizándolo o bloqueándolo:
: inicio SUPERIOR "" %0 ir a ARRIBA
El procesador de comandos cmd.exe que interpreta archivos .cmd es compatible con todas las versiones de 32 bits de Windows hasta Windows 10 y de 64 bits hasta Windows 11. COMMAND.EXE, que interpreta archivos .BAT, fue compatible con las 16 - y versiones de 32 bits hasta al menos Windows 10. [nb 3]
Hay otros lenguajes de scripting, posteriores y más potentes, disponibles para Windows. Sin embargo, estos requieren que se instale el intérprete del lenguaje de secuencias de comandos antes de poder usarlos:
Los archivos de script se ejecutan si se ingresa el nombre del archivo sin extensión. Existen reglas de precedencia que rigen la interpretación de, digamos, DoThis
si existen DoThis.com
, DoThis.exe
, DoThis.bat
, DoThis.cmd
, etc.; por defecto DoThis.com
tiene la máxima prioridad. Este orden predeterminado puede modificarse en 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 del código:ParseArgumentsIntoList, pero es compatible con CRT y .NET Framework.