Windows toplu iş dosyaları: .bat vs .cmd?


747

Anladığım kadarıyla .bat, eski 16 bit adlandırma kuralı ve .cmd32 bit Windows için, yani NT ile başlıyor. Ama her yerde .bat dosyalarını görmeye devam ediyorum ve her iki eki kullanarak da aynı şekilde çalışıyorlar. Benim kod, gerçekten benim toplu dosyaları adlandırmak hangi yolu fark eder NT daha eski bir şey üzerinde çalıştırmanız gerekir, ya da bazı yoktur asla varsayarsak yakaladım yanlış ekini kullanarak beni bekleyen?


19
Sadece karışıklığa eklemek için şimdi .ps1 dosyalarımız var.
Martin Brown

42
Yanılmıyorsam .ps1 dosyaları bir Windows Power Shell dosyası olmalıdır. Yine de yanılmış olabilirim.
CMS_95

Yanıtlar:


454

Gönderen bu haber grup ileti ile Mark Zbikowski kendisi:

CMD.EXE ile ilgili olarak .CMD ve .BAT arasındaki farklar şunlardır: Uzantılar etkinleştirildiğinde, .CMD dosyalarındaki PATH / APPEND / PROMPT / SET / ASSOC hatadan bağımsız olarak ERRORLEVEL değerini ayarlayacaktır. .BAT, ERRORLEVEL ayarını yalnızca hatalarda yapar.

Başka bir deyişle, ERRORLEVEL 0 dışında bir değere ayarlanırsa ve bu komutlardan birini çalıştırırsanız, sonuçta ortaya çıkan ERRORLEVEL:

  • bir .bat dosyasında 0 olmayan değerinde yalnız bırakılır
  • .cmd dosyasında 0 olarak sıfırlayın.

4
Bu, bir .bat komut dosyası kullanmanın bir ERRORLEVEL 0 değerini başarıya döndürmeyeceği anlamına mı geliyor? Eğer bu doğruysa, hiç farketmedim.
djangofan

31
ERRORLEVEL, 0 olmayan olarak ayarlanmışsa, bu komutlardan birini çalıştırırsanız, bir .bat dosyasında tek başına (0 olmayan) bırakılacak, ancak bir .cmd dosyasında 0'a sıfırlanacağı anlamına gelir. Ancak, Windows ne olduğu gibi, aslında, Latince Latin'de "çok önemsiyorsanız ERRORLEVEL'i kendiniz sıfırlayın!"
MadScientist

5
Sadece belirli komutların farklı set / set set eylemlerini yapacağını söylüyor. Diğerleri normal gibi çalışacak
PsychoData

1
Şimdi anlıyorum. Özümü güncelledim. Görünüşe göre, bir set var=..deyimi çağırırken hata seviyesini (yeniden) ayarlamıyor . Bu tuhaf, çünkü bunun beklenen bir davranış olduğunu varsaydım. Her ikisi için de tartışmalar yapılabilir. .Bat dosyalarına sadık kalacağım. :-)
wasatchwizard

1
Not - DPATH /?Yine de komutu APPEND olarak listelemesine rağmen, APPEND komutu belgesiz DPATH komutuyla değiştirilmiştir . Ayrıca, Wiki makalesi DPATH'yi listelememesi dışında çoğunlukla düzeltildi.
dbenham

417

Bu konudaki çeşitli cevaplar ve alıntılanan referanslardan doğrulanmış bilgilerin bir derlemesi:

  1. command.com MS-DOS'ta tanıtılan 16-bit komut işlemcisidir ve Win9x işletim sistemlerinde de kullanılmıştır.
  2. cmd.exeWindows NT'deki 32 bit komut işlemcisidir (64 bit Windows işletim sistemlerinin 64 bit sürümüne de sahiptir). cmd.exeasla Windows 9x'in bir parçası değildi. OS / 2 sürüm 1.0'dan kaynaklandı ve cmd16 bit'in OS / 2 sürümü başladı (ancak yine de komutları olan tam teşekküllü bir korumalı mod programıydı start). Windows NT cmd, OS / 2'den devralındı , ancak Windows NT'nin Win32 sürümü 32 bit ile başladı. OS / 2 1992'de 32 bit olmasına rağmen, cmd16 bit OS / 2 1.x programı olarak kaldı.
  3. ComSpecEnv değişken tanımlar hangi programın tarafından başlatılır .batve .cmdkomut dosyaları. (WinNT ile başlayarak bu varsayılan değerdir cmd.exe.)
  4. cmd.exeile geriye doğru uyumludur command.com.
  5. Windows 9x'te yanlışlıkla yürütülmesini önlemek için tasarlanmış bir komut dosyası cmd.exeadlandırılabilir .cmd. Bu dosya adı uzantısı OS / 2 sürüm 1.0 ve 1987'ye kadar uzanır.

Aşağıda cmd.exedesteklenmeyen özelliklerin bir listesi verilmiştir command.com:

  • Uzun dosya adları (8.3 biçimini aşan)
  • Komut geçmişi
  • Sekme tamamlama
  • Karakteri Escape: ^(Kullanımı için: \ & | > < ^)
  • Dizin yığını: PUSHD/POPD
  • Tam sayı aritmetiği: SET /A i+=1
  • Alt dize / Değiştir / Arama: SET %varname:expression%
  • Komut ikamesi: FOR /F(daha önce vardı, geliştirildi)
  • Fonksiyonlar: CALL :label

Yürütme Sırası:

Bir komut dosyasının hem .bat hem de .cmd sürümleri (test.bat, test.cmd) aynı klasördeyse ve komut dosyasını uzantı (test) olmadan çalıştırırsanız, varsayılan olarak komut dosyasının .bat sürümü de çalışır 64-bit Windows 7'de. Yürütme sırası PATHEXT ortam değişkeni tarafından kontrol edilir. Daha fazla bilgi için bkz. Komut İstemi'nin dosyaları yürütme sırası .

Referanslar:

wikipedia: Komut kabuklarının karşılaştırılması


4
Birkaç küçük nokta: 1) .bat, command.com'u çağırmayabilir - görünüşe göre command.com çağrıldığında biraz karmaşık bir gizemdir; 2) command.com, MS-DOS ile tanıtıldı; 3) cmd.exe, çoğu command.com komut dosyasını çalıştırabilir, ancak cmd'de çalışmayan birkaç küçük command.com öğesi vardır.
Michael Burr

6
cmd.exe, Windows 95 ile değil NT 4.0 ile tanıtıldı.
FlySwat

1
Chris: Wikipedia makalesinin güncel versiyonuna bakın, esp. Mark Zbikowski tarafından açıklama groups.google.com/group/...
Mark

2
Sadece bu konu hakkında bilgi eklemek için: command.com ile dir filenameaynıdır dir filename.*; cmd.exe'de joker kart gereklidir. Command.com'da rem Create an empty file > empty.txtçalışır; cmd.exe içinde değil.
Aacini

2
Bunun sadece bir kısmı OP'nin .bat ve .cmd arasındaki farkla ilgili, command.com ve cmd.exe arasındaki farkla ilgili değil gibi görünüyor. Okuduğumda soru, bir .bat dosyası ile .cmd dosyası arasındaki farkla ilgili, diğer her şey eşit.
Stewart

85

Bu cevaplar biraz fazla uzun ve etkileşimli kullanıma odaklanmış durumda. Komut dosyası oluşturma için önemli farklılıklar şunlardır:

  • .cmd NT olmayan sistemlerde yanlışlıkla yürütülmesini önler.
  • .cmd yerleşik komutların Errorlevel'i başarı olarak 0 olarak değiştirmesini sağlar.

Bu heyecan verici değil, ha?

.cmdDosyalarda, Komut Uzantıları adı verilen bir dizi ek özellik vardı . Ancak artık her ikisi için varsayılan olarak etkindir .batve .cmd2000 ve daha sonra Windows altında dosyaları.

Alt satır: 2012 ve sonrasında, .cmdsadece kullanmanızı öneririm .


7
IMO, ana nokta bu. Daha eski komut dosyalarının 16 bit işletim sistemlerinde yürütülmediğinden emin olmak istediğinizde veya çalışacaklarından emin değilseniz .cmd'yi daha yeni komut dosyaları için uzantı olarak kullanırsınız.
Oliver

12
Üniversite sınıfına benzeyen yararsız tonlarca duvarın üstündeki özlü, pragmatik ve açık cevapları gerçekten takdir ediyorum.
Likit Çekirdek

7
Ben üniversite profesörüyüm ve @Liquid Core'a katılıyorum! Kısa, pragmatik, açık cevaplar nasıl öğreneceğimizdir (henüz bir şey bilmediğimizde). Sonra, bir şekilde, bir kez anladığımızda, onu soyut ve anlaşılmaz bir şekilde açıklama dürtüsünü hissediyoruz. Tuhaf. İyi gözlem!
Eureka

24

Hayır - en ufak bir önemi yok. NT'de .bat ve .cmd uzantılarının her ikisi de cmd.exe işlemcisinin dosyayı tam olarak aynı şekilde işlemesine neden olur.

MS TechNet'ten WinNT sınıfı sistemlerde command.com ve cmd.exe hakkında ek ilginç bilgiler ( http://technet.microsoft.com/en-us/library/cc723564.aspx ):

Bu davranış, Windows NT'nin çok önemli oldukça ince bir özelliğini ortaya çıkarır. Windows NT ile birlikte gelen 16-bit MS-DOS kabuk (COMMAND.COM), Windows NT için özel olarak tasarlanmıştır. Bu kabuk tarafından yürütülmek üzere bir komut girildiğinde, aslında onu yürütmez. Bunun yerine, komut metnini paketler ve yürütme için 32 bit CMD.EXE komut kabuğuna gönderir. Tüm komutlar aslında CMD.EXE (Windows NT komut kabuğu) tarafından yürütüldüğünden, 16-bit kabuk tüm Windows NT kabuğunun tüm özelliklerini ve özelliklerini devralır.


5
Önemli olabilir; bağlantı metninizden bahsedildiği gibi, farklar ince.
Gringo Suave

Komut satırında belirterek, command.com komutunu dos komutunu çalıştırmaya zorlayabilirsiniz. command /c verKomutu başlatma ve ver yazmaya karşı bkz .
phd443322

İsim önemlidir: D Adamların geçmişinden .bat çok gördüm! .Cmd kullanın! Ayrıca NT bugün hala kullanılıyor inanamıyorum ...
hfrmobile

@hfrmobile: 'NT' den bahsettiğimde temelde NT tabanlı olduğumuz tüm Windows sürümlerini kastediyordum (9x değil). Yani aslında NT, Win2k ve XP'den beri masaüstü veya sunucu için Windows'un tüm sürümleri. Ve dosyanın adı, dosyayı yazan kişinin zihniyet ve kodlama stiline ilişkin fikir verebilir, ancak yorumlayıcıya göre hiçbir fark yoktur.
Michael Burr

16

RE: Görünüşe göre command.com çağrıldığında biraz karmaşık bir gizem;

Birkaç ay önce, bir proje sırasında, CMD.EXE altında çalıştırmak istediğimiz bazı programların aslında COMMAND.COM altında çalıştığını anlamak zorundaydık. Söz konusu "program" hala her gün çalışan çok eski bir .BAT dosyasıydı.

Toplu iş dosyasının COMMAND.COM altında çalışmasının nedeninin bir .PIF dosyasından (aynı zamanda eski) başlatılması olduğunu keşfettik. Yalnızca bir PIF aracılığıyla kullanılabilen özel bellek yapılandırma ayarları önemsiz hale geldiğinden, bunu geleneksel bir masaüstü kısayoluyla değiştirdik.

Kısayoldan başlatılan aynı toplu iş dosyası CMD.EXE içinde çalışır. Bunu düşündüğünüzde, bu mantıklı. Anlamak için bu kadar uzun sürmemizin nedeni, kısmen başlangıç ​​grubundaki öğesinin bir PIF olduğunu unutmamamızdan kaynaklanıyordu, çünkü 1998'den beri üretimde.


1
Bu hangi işletim sistemiydi? XP'den önce bir şey mi?
phk

14

Yine de, Windows 7'de BAT dosyaları da bu farka sahiptir: Aynı dizinde TEST.BAT ve TEST.CMD dosyaları oluşturursanız ve bu dizinde TEST çalıştırırsanız, BAT dosyasını çalıştırır.

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>

Bunu yapar, çünkü test.bat test.cmd'den önce alfabetiktir. Windows açgözlü bir tamamlama yapar.
David

26
@David: Doğru değil. Bunun nedeni, PATHEXTdeğişkente .BAT uzantısının .CMD'den önce yerleştirilmesidir (bu yanıtta gösterildiği gibi). Bu siparişi PATHEXT içinde değiştirirseniz, bunun yerine test.cmd yürütülür.
Aacini

Hmm, diğer sırada olmalarını umuyordum; Sanırım MS, mevcut bazı yazılımların .CMD dosyalarını ve .BAT dosyalarını aynı temel adıyla gönderdiğini keşfetmiş olmalı (veya varsayalım) .CMD dosyaları elbette (henüz gönderilmemiş) cmd için giriş olarak tasarlanmamıştır. exe, ancak başka herhangi bir şey olabilirdi: örneğin , başka bir kabuk için komutlar , uygulama tarafından okunan bir yapılandırma komut dosyası veya bir tür uygulama ikili. (En azından, MS'in normalde en uygun olmayan davranışla
sonuçlandığı şeklindeki bu anlayışım

Ayrıca, geçerli dizinin PATH, uzantıya bakılmaksızın ortam değişkenindeki diğer dizinlerden önce geldiğini belirtmek gerekir .
Turkeyphant

13

Orijinal gönderi .bat veya .cmd sonekini kullanmanın sonuçlarıyla ilgili olduğundan , mutlaka dosya içindeki komutlar değil ...

.Bat ve .cmd arasındaki diğer bir fark, aynı dosya adında iki dosya varsa ve bu uzantıların her ikisinin birden olması durumunda:

  • komut satırına dosya adı veya dosya adı .bat girilmesi .bat dosyasını çalıştıracaktır

  • .cmd dosyasını çalıştırmak için, .cmd dosya adını girmeniz gerekir


2
Eh? Benim dizinime bir cmd dosyası koyarsam onu ​​çağırmak için dosya uzantısını belirtmem gerekmez. Örnek: echo notepad.exe% *> np.cmd Sonra sadece "np mytextfilename.txt" yazarsam not defteri getirir. Onu çağırmak için "np.cmd" yazmam gerekmiyor.
Jon Davis

2
@ stimpy77: Bu ad np.cmd bu ada sahip tek dosyaysa, ancak "aynı dosya adına ve her iki uzantıya sahip iki dosya varsa" doğruysa , .cmd dosyasını yürütmenin tek yolu uzantısını dahil etmektir. ..
Aacini

1
Bu, herhangi bir kabuk için belirsizliği çözme zorunluluğudur, .cmd ve .bat arasındaki teknik farklarla ilgisi yoktur. Muhtemelen dosyaadı.bat, dosyaadı.cmd'den alfabetik olarak önce gelir.
Jon Davis

6
Aslında PATHEXTortam değişkenine bağlıdır . Uzantıların göründüğü sıra, bir uzantı belirtilmezse öncelik sırası vardır. Ayrıca, uzantısının env değişkeninde göründüğü dosyalar için bir uzantı belirtmenin gerekli olmadığını da belirtmek gerekir.
Ricardo Zorio

8

bir toplu işte çalışan her şey bir cmd'de çalışmalıdır; cmd, ortamı kontrol etmek için bazı uzantılar sağlar. ayrıca, cmd yeni cmd yorumlayıcısında yürütülür ve bu nedenle yarasa NTVDM benzetimli 16bit ortamında çalıştığından daha hızlı (kısa dosyalarda fark edilmez) ve sabitleyici olmalıdır


Hızda herhangi bir fark yaratmamalıdır. .batNT altında DOS altında çalışmaz. Bir VDM yalnızca bir programın ihtiyacı varsa başlatılır ve 64 bit Windows'da bile desteklenmese de .bat olduğuna inanıyorum.
Gringo Suave

3

.cmd ve .bat dosyalarının yürütülmesi farklıdır çünkü .cmd hata düzeyi değişkeninde, komut uzantılarından etkilenen bir komutta değişebilir. Gerçekten bu kadar.


Kaba ^. ^ Her biri için kullanılan komut dilinde farklılıklar vardır (.bat dosyaları bir uyumluluk sürümü alır). Bunlardan bazıları bu senaryo tarafından buradan görüntülenebilir:@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 dosyalarında her komut hata seviyesini ayarlar, .bat dosyalarında bazı komutlar kabul edilen yanıtta açıklandığı gibi bazı komutlar hata seviyesini değiştirmez
jeb

1
BAT, DOS'un komut yorumlayıcısı olan COMMAND.COM ile etkileşim kurmak için oluşturuldu. Microsoft, DOS komutlarının çoğunu CMD adlı yeni yorumlayıcılarına uyarladı. EXE. CMD, CMD.EXE ile arayüz oluşturmak için oluşturulmuştur ve COMMAND.COM ile uyumluluğu bozmaktadır. esas olarak hata seviyesi değişkenini nasıl ele aldıklarıyla bilinir. BAT kullanılırken, bu değişken yalnızca gerçek bir hata oluştuğunda ve her komut başarıyla yürütüldüğünde durum değişikliği olmadığında değiştirilir. Hata seviyesi olmasa bile hata seviyesi değişkeni hala değişeceğinden, bu CMD için geçerli değildir.
zask

3

ComSpec ortam değişkeninin değerini %SystemRoot%system32\cmd.exe(CMD) olarak değiştirirseniz, dosya uzantısının .BATveya olmaması fark etmez .CMD. Emin değilim, ama bu bile WinXP ve üstü için varsayılan olabilir.


1

Biraz konu dışı, ancak Windows Scripting Host'u düşündünüz mü? Daha güzel bulabilirsiniz.


13
Bu nedenle, WSH / cscript.exe'yi kullanımdan kaldıran PowerShell.
Jon Davis

3
@ stimpy77 Doğru, powershell benim için oldukça korkunç görünüyor.
Marcin

2
WSH'yi çok daha kötü buluyorum. Her şeyin "korkunç" için ölçtüğümüze bağlı olduğunu düşünüyorum. PowerShell'in acımasız başlangıç ​​zamanı var. Bu konuda her şey kesinlikle harika IMO.
Jon Davis

Biçimlendirmeyi affedin, ancak PSH başlangıç ​​zamanını hızlandırmak için çalıştırmayı deneyin: Set-Alias ​​ngen @ (dir (join-path $ {env: \ windir} "Microsoft.NET \ Framework") ngen.exe -recurse | sort -descending lastwritetime) [0] .fullName [YENİ HAT BURADA] [appdomain] :: currentdomain.getassemblies () | % {ngen $ _. location}
mjbnz

1
Tamamen konu dışı.
HappyDog

1

Uzantı hiçbir fark yaratmaz.

COMMAND.COMDosyayı vs ile işlemek arasında küçük farklar vardır CMD.EXE.


-10

bir fark:

.cmd dosyaları yürütülmeden önce belleğe yüklenir. .bat dosyaları bir satırı yürütür, bir sonraki satırı okur, bu satırı yürütür ...

bir komut dosyasını yürüttüğünüzde ve ardından yürütmeden önce düzenlediğinizde bu sorunla karşılaşabilirsiniz. yarasa dosyaları bununla uğraşacak, ama cmd dosyaları olmayacak.


Kurulduğu gibi, ComSpec env değişkeni hangi programın başlatılacağını tanımlar, aslında cmd.exe dosyayı belleğe önceden yüklerken, command.com'un dosyayı bir seferde bir satır okuduğunu mu söylüyorsunuz? Bu konuda bir referans verebilir misiniz?
Chris Noe

24
Vista ve XP için yanlış, her iki dosya türü de satır satır okunur. .Cmd veya .bat dosyasını duraklatır ve düzenlerseniz, yeni kod yürütülür
jeb


1
Komut dosyasının ortasındaki yürütmeyi duraklatır ve başlangıçta bir karakter eklerseniz, ayrıştırıcı kaldığı yerden devam ettikten sonra büyük olasılıkla komut dosyanızın geri kalanını atmak için bir karakter tarafından kapanır.

2
.Bat ve .cmd bu şekilde farklılık göstermemelidir. Her ikisi de her zaman satır satır okunur. Eğer inanmıyorsanız test edebilirsiniz. echo 1&pauseArdından bir toplu iş dosyası oluşturun . Göreceksin 1ve Press any key to continue.... Duraklatıldığında echo 2&pauseharici düzenleyiciye yeni bir satır ekleyin . Bir tuşa basın. Göreceksin 2ve Press any key to continue.... echo 3&pauseBaşlangıçta eklemeyi bile deneyebilirsiniz . Bundan sonra bir tuşa bastığınızda tekrar göreceksiniz 2.
venimus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.