Windowsバッチファイル:.bat vs .cmd?
-
02-07-2019 - |
質問
私が理解しているように、.bat
は古い16ビットの命名規則であり、.cmd
はNTから始まる32ビットWindows用です。しかし、私はどこでも.batファイルを見続けており、どちらのサフィックスを使用してもまったく同じように動作するようです。 NTより古いコードでコードを実行する必要がないと仮定すると、バッチファイルにどのような名前を付けるか、または間違ったサフィックスを使用して私を待っている gotcha が本当に重要ですか?
解決
このニュースグループの投稿から Mark Zbikowski 自身:
CMD.EXEに関する.CMDと.BATの違い 拡張機能を有効にすると、.CMDのPATH / APPEND / PROMPT / SET / ASSOC ファイルはエラーに関係なくERRORLEVELを設定します。 .BATはERRORLEVELを設定します エラー時のみ。
つまり、ERRORLEVELが0以外に設定されている場合、これらのコマンドのいずれかを実行すると、結果のERRORLEVELは次のようになります。
- .batファイルに0以外の値を残します
- .cmdファイルで0にリセットします。
他のヒント
このスレッドのさまざまな回答と引用文献から検証された情報をまとめたものです:
-
command.com
は、MS-DOSで導入された16ビットコマンドプロセッサであり、Win9xシリーズのオペレーティングシステムでも使用されていました。 -
cmd.exe
は、Windows NTの32ビットコマンドプロセッサです(64ビットWindows OSには64ビットバージョンもあります)。cmd
はWindows 9xの一部ではありませんでした。それはOS / 2バージョン1.0で始まり、start
のOS / 2バージョンは16ビットで始まりました(それでもComSpec
のようなコマンドを備えた本格的なプロテクトモードプログラムでした)。 Windows NTはOS / 2から.bat
を継承しましたが、Windows NTのWin32バージョンは32ビットから始まりました。 OS / 2は1992年に32ビットになりましたが、その.cmd
は16ビットOS / 2 1.xプログラムのままでした。 -
^
env変数は、\ & | > < ^
およびPUSHD
スクリプトによって起動されるプログラムを定義します。 (WinNT以降、デフォルトはPOPD
になります。) -
SET /A i+=1
は、SET %varname:expression%
と下位互換性があります。 -
FOR /F
用に設計されたスクリプトには、Windows 9xでの偶発的な実行を防ぐためにCALL :label
という名前を付けることができます。このファイル名拡張子は、OS / 2バージョン1.0および1987にも遡ります。
<=>でサポートされていない<=>機能のリストは次のとおりです。
- 長いファイル名(8.3形式を超える)
- コマンド履歴
- タブ補完
- エスケープ文字:<=>(使用目的:<=>)
- ディレクトリスタック:<=> / <=>
- 整数演算:<=>
- 検索/置換/部分文字列:<=>
- コマンド置換:<=>(以前に存在し、強化されました)
- 機能:<=>
実行の順序:
スクリプトの.batと.cmdの両方のバージョン(test.bat、test.cmd)が同じフォルダーにあり、拡張子(test)なしでスクリプトを実行すると、デフォルトでは、スクリプトの.batバージョンが64ビットWindows 7でも実行できます。実行順序は、PATHEXT環境変数によって制御されます。 詳細については、コマンドプロンプトがファイルを実行する順序。
参照:
wikipedia:コマンドシェルの比較
これらの回答は長すぎて、インタラクティブな使用に焦点を当てています。スクリプトの重要な違いは次のとおりです。
-
.cmd
は、非NTシステムでの不注意な実行を防ぎます。 - <=>を使用すると、組み込みコマンドで成功時にErrorlevelを0に変更できます。
コマンド拡張は、Windows 2000以降の.batファイルと.cmdファイルの両方でデフォルトで有効になっています。
2012年以降は、<=>のみを使用することをお勧めします。
いいえ-少しでも重要ではありません。 NTでは、.batと.cmdの両方の拡張子により、cmd.exeプロセッサはまったく同じ方法でファイルを処理します。
MS TechNetのWinNTクラスシステム上のcommand.comとcmd.exeに関する追加の興味深い情報( http://technet.microsoft.com/en-us/library/cc723564.aspx ):
この動作は非常に微妙なことを明らかにしています 非常にあるWindows NTの機能 重要。 16ビットMS-DOSシェル (COMMAND.COM)Windowsに付属 NTはWindows用に特別に設計されています NT。コマンドが入力されたとき このシェルによる実行、それはしません 実際に実行します。代わりに、それ コマンドテキストをパッケージ化して送信します 32ビットCMD.EXEコマンドシェルに 実行。すべてのコマンドが CMD.EXEによって実際に実行された( Windows NTコマンドシェル)、16ビット シェルはすべての機能を継承し、 完全なWindows NTの機能 シェル。
RE:どうやら、command.comが呼び出されると、少し複雑なミステリーになります;
数か月前、プロジェクトの過程で、CMD.EXEで実行したいプログラムが実際にCOMMAND.COMで実行されていた理由を把握する必要がありました。 <!> quot; program <!> quot;問題は非常に古い.BATファイルで、まだ毎日実行されています。
バッチファイルがCOMMAND.COMの下で実行された理由は、.PIFファイル(以前も同様)から開始されていたためであることがわかりました。 PIFを介してのみ使用できる特別なメモリ構成設定は無関係になったため、従来のデスクトップショートカットに置き換えました。
ショートカットから起動された同じバッチファイルは、CMD.EXEで実行されます。あなたがそれについて考えるとき、これは理にかなっています。それを理解するのに非常に長い時間がかかった理由は、1998年以来生産されていたため、スタートアップグループのアイテムがPIFであることを忘れていたためです。
元の投稿は.batまたは.cmd suffix を使用した結果に関するものであったため、必ずしもファイルの inside コマンドではありません...
.batと.cmdのもう1つの違いは、同じファイル名と両方の拡張子を持つ2つのファイルが存在する場合:
-
コマンドラインで filename または filename .batと入力すると、.batファイルが実行されます
-
.cmdファイルを実行するには、 filename .cmd
を入力する必要があります
さらに、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>
バッチで動作するすべてのものがcmdで動作するはずです。 cmdは、環境を制御するためのいくつかの拡張機能を提供します。 また、cmdは新しいcmdインタープリターで実行されるため、NTVDMエミュレートされた16ビット環境でbatが実行されるため、高速(短いファイルでは目立たない)で安定するはずです
ComSpec環境変数の値を%SystemRoot%system32 \ cmd.exeに変更しても、ファイル拡張子が.BATか.CMDかは問題ではないと思います。確信はありませんが、これはWinXP以降のデフォルトかもしれません。
トピックから少し外れていますが、 Windows Scripting Host を検討しましたか?あなたはそれをより良く見つけるかもしれません。
.cmdと.batファイルの実行は異なります。これは、.cmd errorlevel変数では、コマンド拡張の影響を受けるコマンドで変更される可能性があるためです。それは本当にそれについてです。
拡張子は違いはありません。ファイルを処理するCOMMAND.COMとCMD.EXEにはわずかな違いがあります
ここに私が発見した違いが1つあります。EnableDelayedExpansion
は.cmd
ファイルに必須です。
.bat
ファイルの場合のように、デフォルトでは暗黙的です。 ( Windows 10 )
dir *? | find /i "FOOBAR"
if ERRORLEVEL 0 (
set result="found" ) else (
set result="not found" )
echo %result%
これはfound
で機能しますが、line 2
ファイルの場合は常に<=>です。
<=>を次のように変更すると、期待どおりに動作します。
if %ERRORLEVEL% equ 0 (
そして最後に<=>ファイルに対してこれは正しく動作します:
setLocal EnableDelayedExpansion
...
if !ErrorLevel! equ 1 (
...
違い:
.cmdファイルは、実行される前にメモリにロードされます。 .batファイルは行を実行し、次の行を読み取り、その行を実行します...
スクリプトファイルを実行し、実行が完了する前に編集すると、この問題に遭遇する可能性があります。これにより、batファイルは台無しになりますが、cmdファイルは台無しになりません。