Windowsバッチファイル:.batと.cmd?


747

私が理解しているように、これ.batは古い16ビットの命名規則であり.cmd、32ビットのWindows、つまりNTから始まります。しかし、私はどこにでも.batファイルを見続けており、どちらのサフィックスを使用してもまったく同じように機能するようです。私のコードは、NTよりも古いもので実行する必要はありませんと仮定すると、私は私のバッチファイルに名前を付けている方法は本当に問題でそれをしない、またはいくつかあります知っておかなけれ間違った接尾辞を使用して私を待っているの?


19
混乱を増すために、.ps1ファイルも用意しました。
Martin Brown

42
私が間違っていない場合、.ps1ファイルはWindows Power Shellファイルである必要があります。私は間違っているかもしれません。
CMS_95 2015年

回答:


454

Mark Zbikowski自身によるこのニュースグループの投稿から:

CMD.EXEに関する限り、.CMDと.BATの違いは次のとおりです。拡張機能を有効にすると、エラーに関係なく、.CMDファイルのPATH / APPEND / PROMPT / SET / ASSOCがERRORLEVELを設定します。.BATは、エラーに対してのみERRORLEVELを設定します。

つまり、ERRORLEVELが0以外に設定されている場合に、これらのコマンドのいずれかを実行すると、結果のERRORLEVELは次のようになります。

  • .batファイルで0以外の値のままにする
  • .cmdファイルで0にリセットします。

4
これは、.batスクリプトを使用しても、成功してもERRORLEVEL 0値が返されないことを意味しますか?それが本当なら、私はそれに気づかなかった。
djangofan 2013

31
ERRORLEVELが0以外に設定されている場合、それらのコマンドの1つを実行すると、.batファイルではそれがそのまま(0以外)のまま残りますが、.cmdファイルでは0にリセットされます。しかし、Windowsがそうであるように、Pig Latinで、具体化されていない音声によって「あまり気にしない場合は、ERRORLEVELを自分でリセットしてください!」
MadScientist 2013

5
これらの特定のコマンドのみが異なるセット/セットではないアクションを実行すると言っていると思います。その他は通常どおりに機能します
PsychoData

1
今、私は分かる。要点を更新しました。どうやら、それはset var=..ステートメントを呼び出すときにエラーレベルを(再)設定しません。これは予想外の動作であると想定していたため、これは奇妙です。両方について議論することができます。.batファイルを使います。:-)
wasatchwizard 2015

1
注-APPENDコマンドはドキュメントに記載されていないDPATHコマンドに置き換えられましたが、このコマンドはDPATH /?まだAPPENDとしてリストされています。また、Wikiの記事は、DPATHがリストされていないことを除いて、ほとんどが修正されています。
dbenham 2016年

417

以下は、このスレッド内のさまざまな回答と引用された参照から検証された情報をまとめたものです。

  1. command.com MS-DOSで導入された16ビットコマンドプロセッサで、Win9xシリーズのオペレーティングシステムでも使用されていました。
  2. cmd.exeWindows NTの32ビットコマンドプロセッサです(64ビットWindows OSにも64ビットバージョンがあります)。cmd.exeWindows 9xの一部ではありませんでした。これは、OS / 2バージョン1.0でcmd始まり、OS / 2バージョンの16ビットが始まりました(ただし、のようなコマンドを備えた本格的なプロテクトモードプログラムstartでした)。Windows NT cmdはOS / 2から継承されましたが、Windows NTのWin32バージョンは32ビットで始まりました。OS / 2は1992年に32ビットになりましたcmdが、16ビットOS / 2 1.xプログラムのままでした。
  3. ComSpecENV変数プログラムがによって起動される定義.bat.cmdスクリプト。(WinNTから開始すると、これはデフォルトでになりcmd.exeます。)
  4. cmd.exeはと下位互換性がありcommand.comます。
  5. 用に設計されたスクリプトには、Windows 9xでの偶発的な実行を防ぐためcmd.exeに名前.cmdを付けることができます。このファイル名拡張子は、OS / 2バージョン1.0および1987にも遡ります。

cmd.exeサポートされていない機能のリストを次に示しますcommand.com

  • 長いファイル名(8.3形式を超える)
  • コマンド履歴
  • タブ補完
  • エスケープ文字:^(のための使用:\ & | > < ^
  • ディレクトリスタック:PUSHD/POPD
  • 整数演算: SET /A i+=1
  • 検索/置換/部分文字列: SET %varname:expression%
  • コマンド置換:(FOR /F以前に存在し、拡張されています)
  • 機能: CALL :label

実行の順序:

スクリプトの.batバージョンと.cmdバージョンの両方(test.bat、test.cmd)が同じフォルダーにあり、拡張子(test)なしでスクリプトを実行すると、デフォルトでは、スクリプトの.batバージョンが実行されます。 64ビットWindows 7の場合。実行の順序は、PATHEXT環境変数によって制御されます。詳細については、コマンドプロンプトがファイル実行する順序を参照してください。

参照:

ウィキペディア:コマンドシェルの比較


4
いくつかのマイナーなポイント:1).batは必ずしもcommand.comを呼び出すわけではありません。2)command.comはMS-DOSで導入されました。3)cmd.exeはほとんどのcommand.comスクリプトを実行できますが、cmdで機能しない小さなcommand.comの機能がいくつかあります。
マイケル・バー、

6
cmd.exeは、Windows 95ではなくNT 4.0で導入されました
。– FlySwat

1
クリス:Wikipediaの記事の最新バージョン、特に Mark Zbikowskiのgroups.google.com/group/…
Mark

2
この問題に関する情報を追加するだけです。command.com dir filenameと同じdir filename.*です。ワイルドカードはcmd.exeで必要です。command.comでrem Create an empty file > empty.txt動作します。cmd.exeにはありません。
Aacini、2015年

2
これの少しだけがOPの質問に関連しているようです。これは、.batと.cmdの違いについてであり、command.comとcmd.exeの違いではありません。私がそれを読んだとき、問題は.batファイルと.cmdファイルの違いについてであり、他のすべてのものは同じです。
スチュワート

85

これらの回答は少し長すぎて、インタラクティブな使用に重点を置いています。スクリプトの重要な違いは次のとおりです。

  • .cmd 非NTシステムでの不注意な実行を防止します。
  • .cmd 組み込みコマンドが成功したときにErrorlevelを0に変更できるようにします。

わくわくしませんね。

以前は.cmd、コマンド拡張と呼ばれる、ファイルで有効になっている追加機能がいくつかありました。ただし、Windows 2000以降では、.batおよび.cmdファイルの両方でデフォルトで有効になっています。

結論: 2012年以降は、.cmd排他的に使用することをお勧めします。


7
IMO、それが主なポイントです。新しいスクリプトの拡張子として.cmdを使用して、古い16ビットOSで実行されないようにしたい場合、またはスクリプトが機能するかどうかが不明な場合。
オリバー

12
私は、無駄で大学のクラスのような無数の壁にまたがる簡潔で実用的で明確な答えに本当に感謝しています。
リキッドコア

7
私は大学教授であり、@ Liquid Coreに同意します!簡潔で実用的で明確な答えは、私たちがどのように学習するかです(まだ何かを知らない場合)。そして、どういうわけか、それを理解したら、抽象的で理解しにくい方法で説明したいという衝動を感じます。変だ。良い観察!
ユーレカ

24

いいえ-少しでも問題ありません。NTでは、.batと.cmd拡張子の両方が、cmd.exeプロセッサにまったく同じ方法でファイルを処理させます。

MS TechNet(http://technet.microsoft.com/en-us/library/cc723564.aspx)のWinNTクラスシステムでのcommand.comとcmd.exeに関する追加の興味深い情報:

この動作により、非常に重要なWindows NTの非常に微妙な機能が明らかになります。Windows NTに同梱されている16ビットMS-DOSシェル(COMMAND.COM)は、Windows NT用に特別に設計されています。このシェルで実行するコマンドを入力しても、実際には実行されません。代わりに、コマンドテキストをパッケージ化し、32ビットのCMD.EXEコマンドシェルに送信して実行します。すべてのコマンドは実際にはCMD.EXE(Windows NTコマンドシェル)によって実行されるため、16ビットシェルは完全なWindows NTシェルのすべての機能と機能を継承します。


5
それは重要かもしれません。あなたのリンクテキストが言及するように、違いは微妙です。
Gringo Suave

コマンドラインで指定することで、command.comにdosコマンドを強制的に実行させることができます。command /c vercommand.comの起動とverの入力を比較してください。
phd443322 2014年

名前の問題:Dみんなからの.batの多くは過去のものでした。.cmdを使用してください!NTが今日でも使用されているとは信じられません...
hfrmobile '16

@hfrmobile:私が「NT」について言及したとき、私は基本的に、NTに基づいている(9xではなく)すべてのWindowsバージョンを意味しました。つまり、本質的にはNT、Win2k、およびXP以降のデスクトップまたはサーバー用のWindowsのすべてのバージョンです。そして、ファイルの名前は、ファイルを書いた人の考え方やコーディングスタイルを理解するのに役立ちますが、インタープリターの違いはありません。
Michael Burr 2015

16

RE:どうやらcommand.comがいつ呼び出されるかは少し複雑な謎です。

数か月前、プロジェクトの過程で、CMD.EXEの下で実行したいプログラムが、実際にはCOMMAND.COMの下で実行されている理由を理解する必要がありました。問題の「プログラム」は非常に古い.BATファイルで、毎日実行されます。

バッチファイルがCOMMAND.COMの下で実行された理由は、それが.PIFファイル(これも古い)から開始されたことが原因であることがわかりました。PIFでのみ使用できる特別なメモリ構成設定は無関係になったため、従来のデスクトップショートカットに置き換えました。

ショートカットから起動された同じバッチファイルがCMD.EXEで実行されます。それについて考えるとき、これは理にかなっています。把握に時間がかかった理由の1つは、スタートアップグループの項目がPIFであることを忘れていたためです。


1
これはどのOSでしたか?XPの前に何か?
PHK

14

それでも、Windows 7では、BATファイルにもこの違いがあります。同じディレクトリにTEST.BATとTEST.CMDのファイルを作成し、そのディレクトリでTESTを実行すると、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>

これは、test.batがアルファベット順でtest.cmdの前にあるためです。Windowsは貪欲な補完を行います。
デビッド

26
@David:そうではありません。これは、PATHEXT変数で.BAT拡張子が.CMD拡張子の前に配置されるために発生します(この回答に示されているように)。PATHEXTでこの順序を変更すると、代わりにtest.cmdが実行されます。
Aacini、2015年

うーん、私は彼らが別の順番になっていることを望んでいました。既存のソフトウェアが同じベース名の.CMDファイルと.BATファイルを出荷したことをMSが発見(または想定)したに違いない。 exeですが、他のシェルのコマンド、アプリケーションによって読み取られる構成スクリプト、またはアプリケーションのバイナリなど、さまざまなものである可能性があります。(少なくとも、これはMSが次善の振る舞いをするという通常の方法についての私の理解です。)
SamB '20年

PATH拡張子に関係なく、現在のディレクトリが環境変数内の他のディレクトリの前にあることにも注意してください。
ターキーファント

13

元の投稿は.batまたは.cmd サフィックスを使用した結果に関するものだったので、必ずしもファイルのコマンドではありません...

.batと.cmdのもう1つの違いは、同じファイル名と両方の拡張子を持つ2つのファイルが存在する場合、次のことです。

  • 入力ファイル名ファイル名をコマンドラインでの.batは.BATファイルを実行します

  • .cmdファイルを実行するには、ファイル .cmd を入力する必要があります


2
え?ディレクトリにcmdファイルを配置した場合、それを呼び出すためにファイル拡張子を指定する必要はありません。例:echo notepad.exe%*> np.cmd次に、「np mytextfilename.txt」と入力すると、メモ帳が表示されます。呼び出すために「np.cmd」と入力する必要はありません。
Jon Davis

2
@ stimpy77:これは、np.cmdがその名前の唯一のファイルである場合に当てはまりますが、「同じファイル名で2つのファイルが存在し、両方の拡張子が付いている場合」、.cmdを実行する唯一の方法は拡張子を含めることです。 ..
Aacini、2015年

1
これは、シェルのあいまいさを解決する必要性であり、.cmdと.batの技術的な違いとは関係ありません。これはおそらく、filename.batがfilename.cmdにアルファベット順に先行しているためです。
ジョンデイビス

6
実際にはPATHEXT環境変数に依存します。拡張子が表示される順序は、拡張子が指定されていない場合の優先順位です。拡張子がenv変数に表示されるファイルの拡張子を指定する必要がないことにも言及する価値があります。
Ricardo Zorio

8

バッチで動作するものはすべてcmdで動作するはずです。cmdは、環境を制御するためのいくつかの拡張機能を提供します。また、cmdは新しいcmdインタープリタで実行されるため、NTVDMエミュレートされた16ビット環境でbatを実行すると、高速(短いファイルでは目立たない)で安定するはずです。


速度に違いはありません。 .batNTのDOSでは動作しません。VDMは、プログラムで必要な場合にのみ起動し、64ビットWindowsではサポートされていませんが、.batはそうです。
Gringo Suave

3

.cmdと.batファイルの実行は異なります。.cmderrorlevel変数では、コマンド拡張子の影響を受けるコマンドで変更される可能性があるためです。それは本当にそれについてです。


粗い^。^それぞれに使用されるコマンド言語に違いがあります(.batファイルは互換バージョンを取得します)。これらのいくつかはここからこのスクリプトで説明できます: @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
.cmdファイルでは、すべてのコマンドがエラーレベルを設定し、.batファイルでは、承認された回答に記載されているように、一部のコマンドはエラーレベルを変更しません
jeb

1
BATは、DOSのコマンドインタープリタであるCOMMAND.COMと対話するために作成されました。Microsoftは、ほとんどのDOSコマンドをCMDという名前の新しいインタープリターに採用しました。EXE。CMDはCMD.EXEとのインターフェースとして作成されたものであり、COMMAND.COMとの互換性が失われます。彼らがerrorlevel変数を処理する方法で主に知られています。BATを使用する場合、この変数は実際のエラーが発生したときにのみ変更され、各コマンドが正常に実行されても状態は変化しません。エラーが発生しなくても、errorlevel変数は状態を変更するため、これはCMDには当てはまりません。
zask

3

ComSpec環境変数の値を%SystemRoot%system32\cmd.exe(CMD)に変更した場合、ファイル拡張子が.BATまたはであるかどうかは関係ないと思います.CMD。よくわかりませんが、WinXP以降では、これがデフォルトである可能性もあります。


1

少し話題から外れましたが、Windows Scripting Hostを検討しましたか?あなたはそれがより良いかもしれません。


13
さらに言えば、WSH / cscript.exeを廃止するPowerShell。
ジョンデイビス

3
@ stimpy77はい、ただしpowershellは私にはかなりひどいようです。
Marcin

2
WSHの方がはるかに悪いと思います。それはすべて、私たちが「ひどい」と測定しているものに依存すると思います。PowerShellの起動時間はひどいです。それに関するすべてが絶対に素晴らしいIMOです。
ジョンデイビス

フォーマットをすみませんが、PSHの起動時間を短縮するには、次のコマンドを実行してみてください:Set-Alias ngen @(dir(join-path $ {env:\ windir} "Microsoft.NET \ Framework")ngen.exe -recurse | sort -descending lastwritetime)[0] .fullName [ここに改行] [appdomain] :: currentdomain.getassemblies()| %{ngen $ _。location}
mjbnz 2013年

1
完全にトピックから外れています。
HappyDog

1

拡張機能に違いはありません。

COMMAND.COMファイルの処理との処理にはわずかな違いがありますCMD.EXE


-10

違い:

.cmdファイルは、実行される前にメモリにロードされます。.batファイルは行を実行し、次の行を読み取り、その行を実行します...

スクリプトファイルを実行するときにこれに遭遇し、実行が完了する前に編集できます。batファイルはこれによって混乱しますが、cmdファイルはそうしません。


確立されたように、ComSpec env変数は起動するプログラムを定義します。cmd.exeがファイルをメモリにプリロードしている間、command.comは一度に1行ずつファイルを読み取ると本質的に言っていますか?これについての参照を引用できますか?
Chris Noe

24
VistaとXPでは間違っています。両方のファイルタイプが1行ずつ読み取られます。.cmdまたは.batファイルを一時停止して編集すると、新しいコードが実行されます
jeb


1
コマンドファイルの途中で実行を一時停止し、最初に文字を追加すると、パーサーが再開すると、1文字ずれて残りのスクリプトが破棄される可能性があるため、1行ずつかどうかを議論することができます。

2
.batについては議論しないでください。.cmdはその点で違いはありません。どちらも常に1行ずつ読み取られます。信じられない場合はテストできます。echo 1&pauseそれを実行するバッチファイルを作成します。あなたは見ます1Press any key to continue...。一時停止中にecho 2&pause、外部エディタで新しい行を追加します。キーを押す。あなたは見ます2Press any key to continue...echo 3&pause最初から追加することもできます。その後、もう一度キーを押すと、が表示されます2
venimus
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.