Fichiers batch Windows: .bat vs .cmd?

747

Si je comprends bien, .batc'est l'ancienne convention de dénomination 16 bits, et .cmdc'est pour Windows 32 bits, c'est-à-dire en commençant par NT. Mais je continue de voir des fichiers .bat partout, et ils semblent fonctionner exactement de la même manière en utilisant l'un ou l'autre suffixe. En supposant que mon code ne sera jamais besoin sur quoi que ce soit de plus que NT, est - ce vraiment de quelle manière je nomme mes fichiers batch, ou est - il un Gotcha me attend en utilisant le mauvais suffixe?

Chris Noe
la source
19
Juste pour ajouter à la confusion, nous avons également des fichiers .ps1.
Martin Brown
42
si je ne me trompe pas, les fichiers .ps1 doivent être un fichier Windows Power Shell. Je pourrais toutefois avoir tord.
CMS_95

Réponses:

454

De cette publication de groupe de nouvelles par Mark Zbikowski lui-même:

Les différences entre .CMD et .BAT en ce qui concerne CMD.EXE sont les suivantes: Avec les extensions activées, PATH / APPEND / PROMPT / SET / ASSOC dans les fichiers .CMD définira ERRORLEVEL indépendamment de l'erreur. .BAT définit ERRORLEVEL uniquement sur les erreurs.

En d'autres termes, si ERRORLEVEL est défini sur non-0 et que vous exécutez ensuite l'une de ces commandes, le résultat ERRORLEVEL sera:

  • laissé seul à sa valeur différente de 0 dans un fichier .bat
  • réinitialisé à 0 dans un fichier .cmd.
Ben Hoffstein
la source
4
Cela implique-t-il que l'utilisation d'un script .bat ne retournerait pas une valeur ERRORLEVEL 0 en cas de succès? Si c'est vrai, je ne l'ai jamais remarqué.
djangofan
31
Je pense que cela signifie que si ERRORLEVEL a été défini sur non-0, alors vous exécutez l'une de ces commandes, elle sera laissée seule (non-0) dans un fichier .bat mais réinitialisée à 0 dans un fichier .cmd. Mais, Windows étant ce qu'il est, il est fort possible qu'il provoque en fait une voix désincarnée pour vous dire, en Pig Latin, "réinitialisez ERRORLEVEL si vous vous souciez tellement!".
MadScientist
5
Je pense qu'il dit que seules ces commandes spécifiques feraient les différentes actions set / not set. D'autres fonctionneront comme d'habitude
PsychoData
1
Je comprends maintenant. J'ai mis à jour mon contenu. Apparemment, il ne (re) définit pas le niveau d'erreur lors de l'appel d'une set var=..instruction. Ce qui est étrange, car j'ai supposé que c'était le comportement attendu. Des arguments pourraient être avancés pour les deux. Je m'en tiendrai aux fichiers .bat. :-)
wasatchwizard
1
Remarque - La commande APPEND a été remplacée par la commande DPATH non documentée, bien DPATH /?qu'elle répertorie toujours la commande comme APPEND. De plus, l'article Wiki a depuis été principalement corrigé, sauf qu'il ne répertorie pas DPATH.
dbenham
417

Voici une compilation d'informations vérifiées à partir des différentes réponses et références citées dans ce fil:

  1. command.com est le processeur de commandes 16 bits introduit dans MS-DOS et a également été utilisé dans la série de systèmes d'exploitation Win9x.
  2. cmd.exeest le processeur de commandes 32 bits de Windows NT (les systèmes d'exploitation Windows 64 bits ont également une version 64 bits). cmd.exen'a jamais fait partie de Windows 9x. Il est originaire de OS / 2 version 1.0, et la version OS / 2 de cmd16 bits a commencé (mais était néanmoins un programme en mode protégé à part entière avec des commandes comme start). Windows NT a hérité cmdd'OS / 2, mais la version Win32 de Windows NT a démarré en 32 bits. Bien que OS / 2 soit passé à 32 bits en 1992, il cmdrestait un programme OS / 2 1.x 16 bits.
  3. La ComSpecvariable env définit le programme lancé .batet les .cmdscripts. (À partir de WinNT, cette valeur par défaut est cmd.exe.)
  4. cmd.exeest rétrocompatible avec command.com.
  5. Un script conçu pour cmd.exepeut être nommé .cmdpour empêcher une exécution accidentelle sur Windows 9x. Cette extension de nom de fichier remonte également à OS / 2 version 1.0 et 1987.

Voici une liste de cmd.exefonctionnalités qui ne sont pas prises en charge par command.com:

  • Noms de fichiers longs (dépassant le format 8.3)
  • Historique des commandes
  • Compléter la tabulation
  • Caractère d' échappement: ^(utilisation pour: \ & | > < ^)
  • Pile de répertoires: PUSHD/POPD
  • Arithmétique entière: SET /A i+=1
  • Rechercher / remplacer / sous-chaîne: SET %varname:expression%
  • Substitution de commandes: FOR /F(existait auparavant, a été améliorée)
  • Les fonctions: CALL :label

Ordre d'exécution:

Si les versions .bat et .cmd d'un script (test.bat, test.cmd) se trouvent dans le même dossier et que vous exécutez le script sans l'extension (test), par défaut, la version .bat du script s'exécutera, même sur Windows 64 bits 7. L'ordre d'exécution est contrôlé par la variable d'environnement PATHEXT. Voir Ordre dans lequel l'invite de commandes exécute les fichiers pour plus de détails.

Références:

wikipedia: Comparaison des shells de commande

Chris Noe
la source
4
Plusieurs points mineurs: 1) .bat n'invoque pas nécessairement command.com - apparemment, lorsque command.com est invoqué, c'est un peu un mystère complexe; 2) command.com a été introduit avec MS-DOS; 3) cmd.exe peut exécuter la plupart des scripts command.com, mais il y a quelques petites choses command.com qui ne fonctionnent pas dans cmd.
Michael Burr,
6
cmd.exe a été introduit avec NT 4.0, je crois, pas avec Windows 95.
FlySwat
1
Chris: voir la version actuelle de l'article Wikipedia, esp. le commentaire de Mark Zbikowski sur groups.google.com/group/…
Mark
2
Juste pour ajouter quelques informations à ce sujet: dir filenamec'est la même chose que dir filename.*dans command.com; le caractère générique est requis dans cmd.exe. Dans command.com rem Create an empty file > empty.txtfonctionne; pas dans cmd.exe.
Aacini
2
Seule une petite partie de cela semble être pertinente pour la question de l'OP, qui concerne la différence entre .bat et .cmd, pas la différence entre command.com et cmd.exe. Comme je l'ai lu, la question porte sur la différence entre un fichier .bat et un fichier .cmd, toutes choses étant égales par ailleurs.
Stewart
85

Ces réponses sont un peu trop longues et axées sur une utilisation interactive. Les différences importantes pour les scripts sont les suivantes:

  • .cmd empêche l'exécution accidentelle sur des systèmes non NT.
  • .cmd permet aux commandes intégrées de changer Errorlevel à 0 en cas de succès.

Pas si excitant, hein?

Auparavant, un certain nombre de fonctionnalités supplémentaires étaient activées dans les .cmdfichiers, appelées extensions de commandes. Cependant, ils sont désormais activés par défaut pour les fichiers .batet .cmdsous Windows 2000 et versions ultérieures.

Conclusion: en 2012 et au-delà, je recommande d'utiliser .cmdexclusivement.

Gringo Suave
la source
7
OMI, c'est le point principal. Vous utilisez .cmd comme extension pour les nouveaux scripts lorsque vous voulez vous assurer qu'ils ne sont pas exécutés sur les anciens systèmes d'exploitation 16 bits, ou si vous n'êtes pas sûr qu'ils fonctionneront.
Oliver
12
J'apprécie vraiment les réponses concises, pragmatiques et claires sur des tonnes de murs de réponses inutiles, de type universitaire.
Liquid Core
7
Je suis professeur d'université et je suis d'accord avec @Liquid Core! Des réponses concises, pragmatiques et claires sont la façon dont nous apprenons (quand nous ne savons pas encore quelque chose). Puis, d'une manière ou d'une autre, une fois que nous le comprenons, nous ressentons le besoin de l'expliquer de manière abstraite et incompréhensible. Bizarre. Bonne observation!
Eureka
24

Non, cela n'a aucune importance. Sous NT, l'extension .bat et .cmd entraînent toutes deux le traitement par le processeur cmd.exe du fichier de la même manière.

Informations supplémentaires intéressantes sur command.com par rapport à cmd.exe sur les systèmes de classe WinNT de MS TechNet ( http://technet.microsoft.com/en-us/library/cc723564.aspx ):

Ce comportement révèle une fonctionnalité assez subtile de Windows NT qui est très importante. Le shell MS-DOS 16 bits (COMMAND.COM) fourni avec Windows NT est spécialement conçu pour Windows NT. Lorsqu'une commande est entrée pour être exécutée par ce shell, elle ne l'exécute pas réellement. Au lieu de cela, il conditionne le texte de la commande et l'envoie à un shell de commande CMD.EXE 32 bits pour exécution. Étant donné que toutes les commandes sont réellement exécutées par CMD.EXE (le shell de commandes Windows NT), le shell 16 bits hérite de toutes les fonctionnalités et fonctionnalités du shell Windows NT complet.

Michael Burr
la source
5
Cela peut avoir de l'importance; comme votre texte de lien le mentionne, les différences sont subtiles.
Gringo Suave
Vous pouvez forcer command.com à exécuter une commande dos en la spécifiant sur la ligne de commande. Voir command /c verversus démarrer command.com et taper ver.
phd443322
Le nom compte: D Vu que beaucoup de .bat des gars sont du passé! Utilisez .cmd!
Je
@hfrmobile: Quand j'ai mentionné 'NT', je voulais dire essentiellement toutes les versions de Windows sur lesquelles nous sommes basés sur NT (et non 9x). Donc essentiellement NT, Win2k et toutes les versions de Windows pour le bureau ou le serveur depuis XP. Et le nom du fichier peut donner un aperçu de l'état d'esprit et du style de codage de la personne qui a écrit le fichier, mais pour l'interprète, il n'y a pas de différence.
Michael Burr
16

RE: Apparemment, quand command.com est invoqué, c'est un peu un mystère complexe;

Il y a plusieurs mois, au cours d'un projet, nous avons dû comprendre pourquoi certains programmes que nous voulions exécuter sous CMD.EXE fonctionnaient en fait sous COMMAND.COM. Le "programme" en question était un très ancien fichier .BAT, qui fonctionne toujours quotidiennement.

Nous avons découvert que la raison pour laquelle le fichier de commandes s'exécutait sous COMMAND.COM est qu'il était démarré à partir d'un fichier .PIF (également ancien). Étant donné que les paramètres de configuration de mémoire spéciaux disponibles uniquement via un PIF ne sont plus pertinents, nous l'avons remplacé par un raccourci de bureau classique.

Le même fichier de commandes, lancé à partir du raccourci, s'exécute dans CMD.EXE. Quand on y pense, cela a du sens. La raison pour laquelle il nous a fallu si longtemps pour le comprendre était en partie due au fait que nous avions oublié que son article dans le groupe de démarrage était un PIF, car il était en production depuis 1998.

David Gray
la source
1
Quel OS était-ce? Quelque chose avant XP?
phk
14

Néanmoins, sur Windows 7, les fichiers BAT ont également cette différence: si vous créez des fichiers TEST.BAT et TEST.CMD dans le même répertoire et que vous exécutez TEST dans ce répertoire, il exécutera le fichier 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>
tvCa
la source
Il le fait parce que test.bat est alphabétiquement avant test.cmd. Windows fait un achèvement gourmand.
David
26
@David: Pas vrai. Cela se produit car dans la PATHEXTvariable, l'extension .BAT est placée avant .CMD (comme indiqué dans cette réponse). Si vous modifiez cet ordre dans PATHEXT, le test.cmd serait exécuté à la place.
Aacini
Hmm, j'espérais qu'ils étaient dans l'autre ordre; Je suppose que MS doit avoir découvert (ou supposé) que certains logiciels existants livraient des fichiers .CMD et des fichiers .BAT avec le même nom de base, où les fichiers .CMD n'étaient bien sûr pas destinés à être utilisés pour la cmd (pas encore livrée). exe, mais aurait pu être un certain nombre d'autres choses: des commandes pour un autre shell, un script de configuration lu par l'application, ou une sorte de binaire d'application, par exemple. (Du moins, c'est ma compréhension de la façon habituelle dont la SEP se retrouve avec un comportement apparemment sous-optimal.)
SamB
Il convient également de noter que le répertoire actuel précède les autres répertoires de la PATHvariable d'environnement, quelle que soit l'extension.
Turkeyphant
13

Étant donné que le message d'origine concernait les conséquences de l'utilisation du suffixe .bat ou .cmd , pas nécessairement les commandes à l' intérieur du fichier ...

Une autre différence entre .bat et .cmd est que si deux fichiers existent avec le même nom de fichier et ces deux extensions, alors:

  • la saisie du nom de fichier ou du nom de fichier .bat sur la ligne de commande exécutera le fichier .bat

  • pour exécuter le fichier .cmd, vous devez entrer le nom de fichier .cmd

Rob chez TVSeries.com
la source
2
Eh? Si je mets un fichier cmd dans mon répertoire, je n'ai pas besoin de spécifier l'extension du fichier pour l'invoquer. Exemple: echo notepad.exe% *> np.cmd Ensuite, si je tape simplement "np mytextfilename.txt", il affichera le bloc-notes. Je n'ai pas besoin de taper "np.cmd" pour l'invoquer.
Jon Davis
2
@ stimpy77: Cela est vrai si np.cmd est le seul fichier avec ce nom, mais "si deux fichiers existent avec le même nom de fichier et les deux ces extensions" , alors la seule façon d'exécuter le .cmd est d'inclure son extension. ..
Aacini
1
C'est une nécessité de résoudre l'ambiguïté pour n'importe quel shell, rien à voir avec les différences techniques entre .cmd et .bat. C'est probablement parce que filename.bat précède alphabétiquement filename.cmd.
Jon Davis
6
Cela dépend en fait de la PATHEXTvariable d'environnement. L'ordre dans lequel les extensions apparaissent est l'ordre de priorité si aucune extension n'est spécifiée. Il convient également de mentionner qu'il n'est pas nécessaire de spécifier une extension pour les fichiers dont son extension apparaît dans la variable env.
Ricardo Zorio
8

tout ce qui fonctionne dans un lot devrait fonctionner dans un cmd; cmd fournit quelques extensions pour contrôler l'environnement. également, cmd est exécuté par dans le nouvel interpréteur cmd et devrait donc être plus rapide (non visible sur les fichiers courts) et plus stable lorsque la chauve-souris s'exécute sous l'environnement 16 bits émulé NTVDM

Lorenzo Boccaccia
la source
Cela ne devrait pas faire de différence dans la vitesse. .batne fonctionne pas sous DOS dans NT. Un VDM n'est démarré que si un programme en a besoin et n'est même pas pris en charge dans Windows 64 bits, bien que je pense que .bat l'est.
Gringo Suave
3

L'exécution des fichiers .cmd et .bat est différente car dans une variable de niveau d'erreur .cmd, elle peut changer sur une commande qui est affectée par les extensions de commande. C'est à peu près tout.

zask
la source
De grossier ^. ^ Il y a des différences dans le langage de commande utilisé pour chacun (les fichiers .bat ont une version compatible). Certains d'entre eux peuvent être illustrés par ce script d'ici: @echo off&setlocal ENABLEEXTENSIONS call :func&&echo/I'm a cmd||echo/I'm a bat goto :EOF :func md;2>nul set var=1
zask
4
Dans les fichiers .cmd, chaque commande définit le niveau d'erreur, dans les fichiers .bat, certaines commandes laissent le niveau d'erreur inchangé, comme décrit dans la réponse acceptée
jeb
1
BAT a été créé pour interagir avec COMMAND.COM, l'interpréteur de commandes de DOS. Microsoft a adopté la plupart des commandes DOS dans son nouvel interpréteur nommé CMD. EXE. CMD a été créé pour interfacer avec CMD.EXE et il rompt la compatibilité avec COMMAND.COM. principalement connu pour la façon dont ils gèrent la variable errorlevel. Lors de l'utilisation de BAT, cette variable n'est modifiée qu'une fois qu'une erreur réelle se produit et aucun changement d'état ne se produit lorsque chaque commande s'exécute avec succès. Cela n'est pas vrai pour CMD car la variable errorlevel changerait toujours d'état même si aucune erreur ne se produit.
zask
3

Je crois que si vous changez la valeur de la variable d'environnement ComSpec en %SystemRoot%system32\cmd.exe(CMD), alors peu importe si l'extension de fichier est .BATou .CMD. Je ne suis pas sûr, mais cela peut même être la valeur par défaut pour WinXP et supérieur.

Patrick Cuff
la source
1

Légèrement hors sujet, mais avez-vous envisagé Windows Scripting Host ? Vous pourriez trouver cela plus agréable.

Marcin
la source
13
D'ailleurs, PowerShell, qui déconseille WSH / cscript.exe.
Jon Davis
3
@ stimpy77 Vrai, bien que le PowerShell me semble assez terrible.
Marcin
2
Je trouve WSH bien pire. Je suppose que tout dépend de ce que nous mesurons pour "terrible". PowerShell a un temps de démarrage atroce. Tout est absolument merveilleux OMI.
Jon Davis
Excusez le formatage, mais pour accélérer le démarrage de PSH, essayez d'exécuter: Set-Alias ​​ngen @ (dir (join-path $ {env: \ windir} "Microsoft.NET \ Framework") ngen.exe -recurse | sort -descending lastwritetime) [0] .fullName [NOUVELLE LIGNE ICI] [appdomain] :: currentdomain.getassemblies () | % {ngen $ _. location}
mjbnz
1
Complètement hors sujet.
HappyDog
1

L'extension ne fait aucune différence.

Il existe de légères différences entre la COMMAND.COMgestion du fichier et CMD.EXE.

Waldo
la source
-10

une différence:

Les fichiers .cmd sont chargés en mémoire avant d'être exécutés. Les fichiers .bat exécutent une ligne, lisent la ligne suivante, exécutent cette ligne ...

vous pouvez le rencontrer lorsque vous exécutez un fichier de script, puis l'éditez avant qu'il ne soit terminé. les fichiers bat seront gâchés par cela, mais pas les fichiers cmd.

gris
la source
Comme cela a été établi, la variable env ComSpec définit le programme à lancer, dites-vous essentiellement que command.com lit le fichier ligne par ligne, tandis que cmd.exe précharge le fichier en mémoire? Pouvez-vous citer une référence à ce sujet?
Chris Noe
24
C'est faux pour Vista et XP, les deux types de fichiers sont lus ligne par ligne. Si vous mettez en pause le fichier .cmd ou .bat et le modifiez, le nouveau code sera exécuté
jeb
1
On pourrait se demander si c'est ligne par ligne, car si vous interrompez l'exécution au milieu du fichier de commandes et ajoutez un caractère au début, lors de la reprise, l'analyseur sera désactivé par un caractère, ce qui pourrait éventuellement supprimer le reste de votre script.
2
Vous ne devriez pas débattre de .bat et .cmd ne diffère pas de cette manière. Les deux sont toujours lus ligne par ligne. Vous pouvez le tester si vous n'y croyez pas. Créez un fichier batch qui l'aura echo 1&pauseensuite exécuté. Vous verrez 1et Press any key to continue.... En pause, ajoutez une nouvelle ligne echo 2&pauseavec un éditeur externe. Appuyez sur une touche. Vous verrez 2et Press any key to continue.... Vous pouvez même essayer d'ajouter echo 3&pauseau début. Lorsque vous appuyez à nouveau sur une touche après cela, vous verrez 2.
venimus