Archivos por lotes de Windows: .bat vs .cmd?

Según tengo entendido, .bat es la antigua convención de nombres de 16 bits, y .cmd es para Windows de 32 bits, es decir, que comienza con NT. Pero continúo viendo archivos .bat en todas partes, y parecen funcionar exactamente igual usando cualquiera de los sufijos. Asumiendo que mi código nunca tendrá que ejecutarse en algo más antiguo que NT, ¿realmente importa de qué manera nombro mis archivos de proceso por lotes, o hay algún problema que me espera usando el sufijo incorrecto?

De este grupo de noticias publicado por el propio Mark Zbikowski :

Las diferencias entre .CMD y .BAT en lo que respecta a CMD.EXE son las siguientes: Con las extensiones habilitadas, PATH / APPEND / PROMPT / SET / ASSOC en los archivos .CMD establecerá ERRORLEVEL independientemente del error. .BAT establece ERRORLEVEL solo en los errores.

Aquí hay una comstackción de información verificada de las diversas respuestas y referencias citadas en este hilo:

  1. command.com es el procesador de comandos de 16 bits introducido en MS-DOS y también se usó en la serie de sistemas operativos Win9x.
  2. cmd.exe es el procesador de comandos de 32 bits en Windows NT (los sistemas operativos de 64 bits de Windows también tienen una versión de 64 bits). cmd.exe nunca fue parte de Windows 9x. Se originó en OS / 2 versión 1.0 y la versión OS / 2 de cmd comenzó en 16 bits (pero, no obstante, era un progtwig en modo protegido con comandos como start ). Windows NT heredó cmd de OS / 2, pero la versión Win32 de Windows NT comenzó en 32 bits. Aunque OS / 2 fue de 32 bits en 1992, su cmd siguió siendo un progtwig OSx 2x de 16 bits.
  3. La variable de ComSpec ComSpec define qué progtwig se inicia con las secuencias de comandos .bat y .cmd . (Comenzando con WinNT, este es el valor predeterminado de cmd.exe ).
  4. cmd.exe es compatible con command.com .
  5. Un script diseñado para cmd.exe se puede .cmd para evitar la ejecución accidental en Windows 9x. Esta extensión de nombre de archivo también se remonta a OS / 2 versión 1.0 y 1987.

Aquí hay una lista de características de cmd.exe que no son compatibles con command.com :

  • Nombres de archivo largos (que superan el formato 8.3)
  • Historial de comandos
  • Completar pestaña
  • Carácter de escape: ^ (Usar para: \ & | > < ^ )
  • Pila de directorio: PUSHD / POPD
  • Aritmética de enteros: SET /A i+=1
  • Buscar / Reemplazar / Subcadena: SET %varname:expression%
  • Sustitución de comando: FOR /F (existía antes, se ha mejorado)
  • Funciones: CALL :label

Orden de ejecución:

Si las versiones .bat y .cmd de un script (test.bat, test.cmd) están en la misma carpeta y ejecuta el script sin la extensión (prueba), de forma predeterminada se ejecutará la versión .bat del script, incluso en Windows 7 de 64 bits. El orden de ejecución está controlado por la variable de entorno PATHEXT. Consulte Orden en la que símbolo del sistema ejecuta archivos para obtener más detalles.

Referencias

  • cmd.exe
  • command.com

wikipedia: Comparación de las conchas de comando

Estas respuestas son demasiado largas y se centran en el uso interactivo. Las diferencias importantes son:

  • .cmd previene la ejecución inadvertida en sistemas que no son NT.
  • .cmd habilita los comandos incorporados para cambiar Errorlevel a 0 en caso de éxito.

Editar: las Extensiones de comandos están activadas por defecto en los archivos .bat y .cmd en Windows 2000 o posterior.

En 2012 y más adelante, recomiendo usar .cmd exclusivamente.

No, no importa en lo más mínimo. En NT, la extensión .bat y .cmd hacen que el procesador cmd.exe procese el archivo exactamente de la misma manera.

Información adicional interesante sobre command.com vs. cmd.exe en sistemas WinNT-class de MS TechNet ( http://technet.microsoft.com/en-us/library/cc723564.aspx ):

Este comportamiento revela una característica bastante sutil de Windows NT que es muy importante. El shell de MS-DOS de 16 bits (COMMAND.COM) que se envía con Windows NT está especialmente diseñado para Windows NT. Cuando un shell es ingresado para ser ejecutado por este shell, en realidad no lo ejecuta. En su lugar, empaqueta el texto del comando y lo envía a un shell de comandos CMD.EXE de 32 bits para su ejecución. Debido a que todos los comandos son realmente ejecutados por CMD.EXE (el shell de comandos de Windows NT), el shell de 16 bits hereda todas las funciones e instalaciones del shell completo de Windows NT.

RE: Aparentemente cuando se invoca a command.com es un misterio complejo;

Hace varios meses, durante el curso de un proyecto, tuvimos que descubrir por qué algunos progtwigs que queríamos ejecutar bajo CMD.EXE, de hecho, se ejecutaban bajo COMMAND.COM. El “progtwig” en cuestión era un archivo .BAT muy viejo, que aún se ejecuta diariamente.

Descubrimos que la razón por la que el archivo por lotes se ejecutó en COMMAND.COM es que se inició desde un archivo .PIF (también antiguo). Como las configuraciones de memoria especiales disponibles solo a través de un PIF se han vuelto irrelevantes, las reemplazamos con un atajo de escritorio convencional.

El mismo archivo de proceso por lotes, iniciado desde el acceso directo, se ejecuta en CMD.EXE. Cuando lo piensas, esto tiene sentido. El motivo por el que nos tomó tanto tiempo resolverlo se debió en parte al hecho de que habíamos olvidado que su artículo en el grupo de inicio era un PIF, porque había estado en producción desde 1998.

Dado que la publicación original se refería a las consecuencias de usar el sufijo .bat o .cmd, no necesariamente los comandos dentro del archivo …

Otra diferencia entre .bat y .cmd es que si existen dos archivos con el mismo nombre de archivo y ambas extensiones, entonces:

  • Al ingresar el nombre de archivo o nombre de archivo .bat en la línea de comando se ejecutará el archivo .bat

  • para ejecutar el archivo .cmd, debe ingresar el nombre de archivo .cmd

Aún así, en Windows 7, los archivos BAT también tienen esta diferencia: si alguna vez crea archivos TEST.BAT y TEST.CMD en el mismo directorio, y ejecuta TEST en ese directorio, ejecutará el archivo BAT.

 C:\>echo %PATHEXT% .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC C:\Temp>echo echo bat > test.bat C:\Temp>echo echo cmd > test.cmd C:\Temp>test C:\Temp>echo bat bat C:\Temp> 

todo lo que funcione en un lote debería funcionar en un cmd; cmd proporciona algunas extensiones para controlar el entorno. Además, cmd se ejecuta en un nuevo intérprete de cmd y, por lo tanto, debe ser más rápido (no se nota en los archivos cortos) y más estable a medida que bat se ejecuta bajo el entorno de 16 bits emulado por NTVDM.

Creo que si cambia el valor de la variable de entorno ComSpec a% SystemRoot% system32 \ cmd.exe, entonces no importa si la extensión del archivo es .BAT o .CMD. No estoy seguro, pero esto puede ser el predeterminado para WinXP y superior.

Un poco fuera de tema, pero ¿has considerado Windows Scripting Host ? Puede que lo encuentres más agradable.

La ejecución del archivo .cmd y .bat es diferente porque en una variable .cmd errorlevel puede cambiar en un comando que se ve afectado por las extensiones de comando. Eso es todo realmente.

La extensión no hace diferencia. Existen pequeñas diferencias entre COMMAND.COM que maneja el archivo vs. CMD.EXE

Aquí hay una diferencia que descubrí: EnableDelayedExpansion es obligatorio en los archivos .cmd .
Donde, como en el caso de los archivos .bat , está implícito por defecto. ( Windows 10 )

 dir *? | find /i "FOOBAR" if ERRORLEVEL 0 ( set result="found" ) else ( set result="not found" ) echo %result% 

Esto funciona en .bat pero siempre se found en el caso de un archivo .cmd .
Cambiar la line 2 a la siguiente hace que funcione como se esperaba:

 if %ERRORLEVEL% equ 0 ( 

Y finalmente para el archivo .cmd esto funciona correctamente:

 setLocal EnableDelayedExpansion ... if !ErrorLevel! equ 1 ( ... 

Como es un progtwigdor de Cmd, y busca en toda la web, realmente no importa cuál use, puede tener un progtwig .bat en un Windows 7 y ejecutarlo en un Windows 10. Pero si va a hacer en un Windows 10, probablemente no podrá ejecutar todos los comandos en Windows 7. A .cmd es exactamente de la misma manera, y ejecuta exactamente el mismo progtwig y códigos.

La única diferencia es que es un nombre diferente del mismo progtwig, siempre que esté conectado a CMD.EXE , ejecuta los mismos comandos.

una diferencia:

Los archivos .cmd se cargan en la memoria antes de ejecutarse. Los archivos .bat ejecutan una línea, leen la siguiente línea, ejecutan esa línea …

puede encontrar esto cuando ejecuta un archivo de script y luego edítelo antes de que se haya ejecutado. Los archivos bat se verán afectados por esto, pero los archivos cmd no lo harán.