Tập tin lô Windows: .bat so với .cmd?


747

Theo tôi hiểu, đây .batlà quy ước đặt tên 16 bit cũ và .cmddành cho Windows 32 bit, tức là bắt đầu bằng NT. Nhưng tôi tiếp tục thấy các tệp .bat ở khắp mọi nơi và chúng dường như hoạt động giống hệt nhau bằng cách sử dụng hậu tố. Giả sử rằng mã của tôi sẽ không bao giờ cần phải chạy trên bất cứ thứ gì cũ hơn NT, việc tôi đặt tên cho các tệp bó của mình có thực sự quan trọng không, hoặc có một số gotcha đang chờ tôi bằng cách sử dụng hậu tố sai?


19
Chỉ cần thêm vào sự nhầm lẫn, bây giờ chúng ta cũng có các tệp .ps1.
Martin Brown

42
nếu tôi không nhầm tệp .ps1 sẽ là tệp Windows Power Shell. Tôi có thể sai mặc dù.
CMS_95

Câu trả lời:


454

Từ nhóm tin tức này được đăng bởi chính Mark Zbikowski :

Sự khác biệt giữa .CMD và .BAT liên quan đến CMD.EXE là: Với các tiện ích mở rộng được bật, PATH / APPEND / PROMPT / SET / ASSOC trong các tệp .CMD sẽ đặt ERRORLEVEL bất kể lỗi. .BAT chỉ đặt ERRORLEVEL cho các lỗi.

Nói cách khác, nếu ERRORLEVEL được đặt thành 0 và sau đó bạn chạy một trong các lệnh đó, kết quả ERRORLEVEL sẽ là:

  • còn lại một mình ở giá trị khác 0 của nó trong tệp .bat
  • đặt lại về 0 trong tệp .cmd.

4
Điều đó có nghĩa là việc sử dụng tập lệnh .bat sẽ không trả về giá trị ERRORLEVEL 0 khi thành công? Nếu đó là sự thật, tôi không bao giờ nhận thấy nó.
djangofan

31
Tôi nghĩ điều đó có nghĩa là nếu ERRORLEVEL được đặt thành 0, thì bạn chạy một trong các lệnh đó, nó sẽ được để lại một mình (không phải 0) trong tệp .bat nhưng được đặt lại về 0 trong tệp .cmd. Nhưng, Windows là như vậy, hoàn toàn có thể nó thực sự gây ra tiếng nói khinh bỉ để nói với bạn, trong Pig Latin, "hãy tự thiết lập lại ERRORLEVEL nếu bạn quan tâm quá nhiều!".
MadSellectist

5
Tôi nghĩ rằng nó chỉ nói rằng những lệnh cụ thể sẽ thực hiện các hành động thiết lập / không thiết lập khác nhau. Những người khác sẽ hoạt động như bình thường
PsychoData

1
Giờ thì tôi đã hiểu. Tôi cập nhật ý chính của tôi. Rõ ràng, nó không (tái) đặt errorlevel khi gọi một set var=..câu lệnh. Đó là kỳ lạ, bởi vì tôi cho rằng đó là hành vi dự kiến. Đối số có thể được thực hiện cho cả hai. Tôi sẽ gắn bó với các tập tin .bat. :-)
wasatchwizard

1
Lưu ý - Lệnh APPEND đã được thay thế bằng lệnh DPATH không có giấy tờ, mặc dù DPATH /?vẫn liệt kê lệnh là APPEND. Ngoài ra, bài viết Wiki đã được sửa chữa hầu hết, ngoại trừ nó không liệt kê DPATH.
dbenham

417

Dưới đây là tổng hợp các thông tin được xác minh từ các câu trả lời khác nhau và các tài liệu tham khảo được trích dẫn trong chủ đề này:

  1. command.com là bộ xử lý lệnh 16 bit được giới thiệu trong MS-DOS và cũng được sử dụng trong loạt hệ điều hành Win9x.
  2. cmd.exelà bộ xử lý lệnh 32 bit trong Windows NT (HĐH Windows 64 bit cũng có phiên bản 64 bit). cmd.exechưa bao giờ là một phần của Windows 9x. Nó bắt nguồn từ phiên bản OS / 2 1.0 và phiên bản OS / 2 cmdđã bắt đầu 16 bit (nhưng dù sao đó cũng là một chương trình chế độ được bảo vệ đầy đủ với các lệnh như start). Windows NT được thừa hưởng cmdtừ OS / 2, nhưng phiên bản Win32 của Windows NT đã khởi động 32 bit. Mặc dù OS / 2 đã đi 32 bit vào năm 1992, nhưng nó cmdvẫn là chương trình OS / 2 1.x 16 bit.
  3. Biến ComSpecenv xác định chương trình nào được khởi chạy bởi .bat.cmdscript. (Bắt đầu với WinNT, mặc định này là cmd.exe.)
  4. cmd.exelà tương thích ngược với command.com.
  5. Một tập lệnh được thiết kế cho cmd.execó thể được đặt tên .cmdđể ngăn việc thực thi ngẫu nhiên trên Windows 9x. Phần mở rộng tên tệp này cũng có từ phiên bản OS / 2 1.0 và 1987.

Dưới đây là danh sách các cmd.exetính năng không được hỗ trợ bởi command.com:

  • Tên tệp dài (vượt quá định dạng 8.3)
  • Lịch sử chỉ huy
  • Hoàn thành tab
  • Nhân vật thoát: ^(Sử dụng cho \ & | > < ^:)
  • Ngăn xếp thư mục: PUSHD/POPD
  • Số học số nguyên: SET /A i+=1
  • Tìm kiếm / Thay thế / Chuỗi con: SET %varname:expression%
  • Thay thế lệnh: FOR /F(tồn tại trước đó, đã được tăng cường)
  • Chức năng: CALL :label

Lệnh thi hành:

Nếu cả hai phiên bản .bat và .cmd của tập lệnh (test.bat, test.cmd) nằm trong cùng một thư mục và bạn chạy tập lệnh mà không có phần mở rộng (kiểm tra), theo mặc định, phiên bản .bat của tập lệnh sẽ chạy, thậm chí trên Windows 64 bit 7. Thứ tự thực hiện được điều khiển bởi biến môi trường PATHEXT. Xem thứ tự trong đó Command Prompt thực thi các tệp để biết thêm chi tiết.

Người giới thiệu:

wikipedia: So sánh các shell lệnh


4
Một số điểm nhỏ: 1) .bat không nhất thiết phải gọi lệnh.com - rõ ràng khi lệnh.com được gọi là một chút bí ẩn phức tạp; 2) lệnh.com được giới thiệu với MS-DOS; 3) cmd.exe có thể chạy hầu hết các tập lệnh Command.com, nhưng có một vài điều lệnh.com không hoạt động trong cmd.
Michael Burr

6
Tôi tin rằng cmd.exe đã được giới thiệu với NT 4.0, không phải windows 95.
FlySwat

1
Chris: xem phiên bản hiện tại của bài viết Wikipedia, đặc biệt. nhận xét của Mark Zbikowski tại Groups.google.com/group/
Mark

2
Chỉ cần thêm một số thông tin về vấn đề này: dir filenamegiống như dir filename.*trong lệnh.com; thẻ đại diện được yêu cầu trong cmd.exe. Trong lệnh.com rem Create an empty file > empty.txthoạt động; không có trong cmd.exe.
Aacini

2
Chỉ một chút điều này dường như có liên quan đến câu hỏi của OP, đó là về sự khác biệt giữa .bat và .cmd, không phải là sự khác biệt giữa lệnh.com và cmd.exe. Khi tôi đọc nó, câu hỏi là về sự khác biệt giữa tệp .bat và tệp .cmd, tất cả những thứ khác đều bằng nhau.
Stewart

85

Những câu trả lời này hơi dài và tập trung vào việc sử dụng tương tác. Sự khác biệt quan trọng cho kịch bản là:

  • .cmd ngăn chặn việc thực hiện vô ý trên các hệ thống phi NT.
  • .cmd cho phép các lệnh tích hợp để thay đổi Errorlevel thành 0 khi thành công.

Không thú vị lắm hả?

Đã từng có một số tính năng bổ sung được kích hoạt trong .cmdcác tệp, được gọi là Phần mở rộng lệnh. Tuy nhiên, giờ đây chúng được bật theo mặc định cho cả hai .bat.cmdtệp trong Windows 2000 trở lên.

Điểm mấu chốt: trong năm 2012 và hơn thế nữa, tôi khuyên bạn nên sử dụng .cmdđộc quyền.


7
IMO, đó là điểm chính. Bạn sử dụng .cmd làm tiện ích mở rộng cho các tập lệnh mới hơn khi bạn muốn đảm bảo rằng chúng không được thực thi trên các HĐH 16 bit cũ hơn hoặc nếu bạn không chắc chắn chúng sẽ hoạt động.
Oliver

12
Tôi thực sự đánh giá cao câu trả lời súc tích, thực dụng và rõ ràng qua hàng tấn bức tường của những câu trả lời giống như lớp học đại học vô dụng.
Lõi lỏng

7
Tôi là giáo sư đại học và tôi đồng ý với @L Liquid Core! Câu trả lời ngắn gọn, thực tế, rõ ràng là cách chúng ta học (khi chúng ta chưa biết điều gì). Sau đó, bằng cách nào đó, một khi chúng ta hiểu nó, chúng ta cảm thấy thôi thúc phải giải thích nó một cách trừu tượng và khó hiểu. Kỳ dị. Quan sát tốt!
Eureka

24

Không - nó không quan trọng trong một chút. Trên NT, phần mở rộng .bat và .cmd đều khiến bộ xử lý cmd.exe xử lý tệp theo cùng một cách chính xác.

Thông tin thú vị khác về lệnh.com so với cmd.exe trên các hệ thống lớp WinNT từ MS TechNet ( http://technet.microsoft.com/en-us/l Library / cc723564.aspx ):

Hành vi này cho thấy một tính năng khá tinh tế của Windows NT rất quan trọng. Vỏ MS-DOS 16 bit (HOL.COM) đi kèm với Windows NT được thiết kế đặc biệt cho Windows NT. Khi một lệnh được nhập để thực thi bởi shell này, nó không thực sự thực thi nó. Thay vào đó, nó đóng gói văn bản lệnh và gửi nó đến một vỏ lệnh 32-bit CMD.EXE để thực thi. Vì tất cả các lệnh thực sự được thực hiện bởi CMD.EXE (shell lệnh Windows NT), shell 16 bit thừa hưởng tất cả các tính năng và tiện ích của vỏ Windows NT đầy đủ.


5
Nó có thể quan trọng; như văn bản liên kết của bạn đề cập đến sự khác biệt là tinh tế.
Gringo Suave

Bạn có thể buộc lệnh.com thực thi lệnh dos bằng cách chỉ định nó trên dòng lệnh. Xem command /c verso với bắt đầu lệnh.com và gõ ver.
phd443322

Tên vấn đề: D Đã thấy rất nhiều .bat từ những người đến từ quá khứ! Sử dụng .cmd! Cũng không thể tin rằng NT vẫn được sử dụng cho đến ngày hôm nay ...
hfrmobile

@hfrmobile: Khi tôi đề cập đến 'NT', tôi có nghĩa là về cơ bản tất cả các phiên bản Windows mà chúng tôi dựa trên NT (chứ không phải 9x). Vì vậy, về cơ bản NT, Win2k và tất cả các phiên bản Windows cho máy tính để bàn hoặc máy chủ kể từ XP. Và tên của tệp có thể cung cấp cái nhìn sâu sắc về tư duy và phong cách mã hóa của người đã viết tệp, nhưng theo như thông dịch viên thì không có sự khác biệt.
Michael Burr

16

RE: Rõ ràng khi lệnh.com được gọi là một chút bí ẩn phức tạp;

Cách đây vài tháng, trong quá trình thực hiện một dự án, chúng tôi đã phải tìm ra lý do tại sao một số chương trình mà chúng tôi muốn chạy trong CMD.EXE, trên thực tế, lại chạy dưới điều chỉnh.COM. "Chương trình" trong câu hỏi là một tệp .BAT rất cũ, vẫn chạy hàng ngày.

Chúng tôi đã phát hiện ra rằng lý do tệp bó chạy trong THÔNG TIN là vì nó được bắt đầu từ tệp .PIF (cũng cổ). Do các cài đặt cấu hình bộ nhớ đặc biệt chỉ có sẵn thông qua PIF đã trở nên không liên quan, chúng tôi đã thay thế nó bằng một phím tắt trên màn hình thông thường.

Tệp bó tương tự, được khởi chạy từ phím tắt, chạy trong CMD.EXE. Khi bạn nghĩ về nó, điều này có ý nghĩa. Lý do khiến chúng tôi mất nhiều thời gian để tìm ra nó một phần là do chúng tôi đã quên rằng sản phẩm của nó trong nhóm khởi nghiệp là PIF, vì nó đã được sản xuất từ ​​năm 1998.


1
Hệ điều hành này là gì? Cái gì trước XP?
phk

14

Tuy nhiên, trên Windows 7, các tệp BAT cũng có sự khác biệt này: Nếu bạn từng tạo tệp TEST.BAT và TEST.CMD trong cùng thư mục và bạn chạy TEST trong thư mục đó, nó sẽ chạy tệp 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>

Nó làm điều đó bởi vì test.bat được sắp xếp theo thứ tự abc trước test.cmd. Windows hoàn thành tham lam.
David

26
@David: Không đúng. Điều này xảy ra bởi vì trong PATHEXTbiến, phần mở rộng .BAT được đặt trước .CMD một (như thể hiện trong câu trả lời này). Nếu bạn sửa đổi thứ tự này trong PATHEXT, test.cmd sẽ được thực thi thay thế.
Aacini

Hmm, tôi đã hy vọng họ theo thứ tự khác; Tôi đoán MS phải phát hiện (hoặc giả định) rằng một số phần mềm hiện có đã gửi các tệp .CMD và các tệp .BAT có cùng tên cơ sở, trong đó các tệp .CMD tất nhiên không được dùng làm đầu vào cho cmd (chưa được vận chuyển). exe, nhưng có thể là bất kỳ số lượng nào khác: các lệnh cho một số shell khác , tập lệnh cấu hình được đọc bởi ứng dụng hoặc một loại nhị phân ứng dụng nào đó, chẳng hạn. (Ít nhất, đó là sự hiểu biết của tôi về cách thông thường MS kết thúc với hành vi dường như không tối ưu.)
SamB

Cũng đáng lưu ý rằng thư mục hiện tại xuất hiện trước các thư mục khác trong PATHbiến môi trường bất kể phần mở rộng.
Thổ Nhĩ Kỳ

13

Vì bài đăng gốc liên quan đến hậu quả của việc sử dụng hậu tố .bat hoặc .cmd , không nhất thiết phải là các lệnh bên trong tệp ...

Một sự khác biệt khác giữa .bat và .cmd là nếu hai tệp tồn tại cùng tên tệp và cả hai phần mở rộng đó thì:

  • nhập tên tệp hoặc tên tệp .bat tại dòng lệnh sẽ chạy tệp .bat

  • để chạy tệp .cmd, bạn phải nhập tên tệp .cmd


2
Hở? Nếu tôi đặt tệp cmd trong thư mục của mình, tôi không phải chỉ định phần mở rộng tệp để gọi nó. Ví dụ: echo notepad.exe% *> np.cmd Sau đó, nếu tôi chỉ gõ "np mytextfilename.txt", nó sẽ hiển thị notepad. Tôi không phải gõ "np.cmd" để gọi nó.
Jon Davis

2
@ activpy77: Điều này đúng nếu np.cmd là tệp duy nhất có tên đó, nhưng "nếu hai tệp tồn tại cùng tên tệp và cả hai phần mở rộng đó" , thì cách duy nhất để thực thi tệp .cmd là bao gồm phần mở rộng của nó. ..
Aacini

1
Đây là một điều cần thiết để giải quyết sự mơ hồ cho bất kỳ shell nào, không liên quan gì đến sự khác biệt kỹ thuật giữa .cmd so với .bat. Có lẽ vì filename.bat có trước tên tệp.cmd theo thứ tự bảng chữ cái.
Jon Davis

6
Nó thực sự phụ thuộc vào PATHEXTbiến môi trường. Thứ tự trong các phần mở rộng xuất hiện có thứ tự ưu tiên nếu phần mở rộng không được chỉ định. Một điều đáng nói nữa là không cần thiết phải chỉ định một phần mở rộng cho các tệp mà phần mở rộng của nó xuất hiện trong biến env.
Ricardo Zorio

8

tất cả mọi thứ làm việc trong một lô nên làm việc trong một cmd; cmd cung cấp một số phần mở rộng để kiểm soát môi trường. Ngoài ra, cmd được thực thi bởi trình thông dịch cmd mới và do đó sẽ nhanh hơn (không đáng chú ý trên các tệp ngắn) và stabler khi dơi chạy trong môi trường 16bit giả lập NTVDM


Không nên làm cho bất kỳ sự khác biệt về tốc độ. .batkhông chạy dưới DOS trong NT. VDM chỉ được khởi động nếu một chương trình cần nó và thậm chí không được hỗ trợ trong Windows 64 bit, mặc dù tôi tin .bat là vậy.
Gringo Suave

3

Thực thi tập tin .cmd và .bat là khác nhau bởi vì trong một biến lỗi .cmd, nó có thể thay đổi trên một lệnh bị ảnh hưởng bởi các phần mở rộng lệnh. Đó là về nó thực sự.


Của thô ^. ^ Có sự khác biệt trong ngôn ngữ lệnh được sử dụng cho mỗi (tệp .bat có phiên bản tương thích). Một số trong số này có thể được minh họa bằng kịch bản này từ đây: @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
Trong các tệp .cmd, mỗi lệnh sẽ đặt errorlevel, trong các tệp .bat một số lệnh giữ nguyên lỗi không thay đổi, như được mô tả trong câu trả lời được chấp nhận
jeb

1
BAT được tạo ra để tương tác với HOL.COM, trình thông dịch lệnh của DOS. Microsoft đã áp dụng hầu hết các lệnh DOS vào trình thông dịch mới có tên là CMD. EXE. CMD được tạo để giao diện với CMD.EXE và nó phá vỡ tính tương thích với HOL.COM. chủ yếu được biết đến với cách họ xử lý biến errorlevel. Khi sử dụng BAT, biến này chỉ được thay đổi khi xảy ra lỗi thực tế và không có thay đổi trạng thái xảy ra khi mỗi lệnh thực thi thành công. Điều này không đúng với CMD vì biến errorlevel vẫn sẽ thay đổi trạng thái ngay cả khi không có lỗi xảy ra.
số

3

Tôi tin rằng nếu bạn thay đổi giá trị của biến môi trường ComSpec thành %SystemRoot%system32\cmd.exe(CMD) thì không vấn đề gì nếu phần mở rộng tệp là .BAThoặc .CMD. Tôi không chắc chắn, nhưng điều này thậm chí có thể là mặc định cho WinXP trở lên.


1

Hơi lạc đề, nhưng bạn đã xem xét Windows Scripting Host chưa? Bạn có thể thấy nó đẹp hơn.


13
Đối với vấn đề đó, PowerShell, không dùng WSH / cscript.exe.
Jon Davis

3
@ activpy77 Đúng, mặc dù powershell có vẻ khá khủng khiếp đối với tôi.
Marcin

2
Tôi thấy WSH tồi tệ hơn nhiều. Tôi cho rằng tất cả phụ thuộc vào những gì chúng ta đang đo lường cho "khủng khiếp". PowerShell có thời gian khởi động tồi tệ. Tất cả mọi thứ về nó là IMO hoàn toàn tuyệt vời.
Jon Davis

Xin lỗi định dạng, nhưng để tăng tốc thời gian khởi động PSH, hãy thử chạy: Set-Alias ​​ngen @ (dir (đường dẫn tham gia $ {env: \ Windir} "Microsoft.NET \ Framework") ngen.exe -recurse | sort -desceinating Lastwritetime) [0] .fullName [LINE MỚI TẠI ĐÂY] [appdomain] :: currentdomain.getassemblies () | % {ngen $ _. location}
mjbnz

1
Hoàn toàn lạc đề.
HappyDog

1

Phần mở rộng làm cho không có sự khác biệt.

Có một chút khác biệt giữa việc COMMAND.COMxử lý tệp so với CMD.EXE.


-10

một sự khác biệt:

Các tập tin .cmd được tải vào bộ nhớ trước khi được thực thi. Các tập tin .bat thực thi một dòng, đọc dòng tiếp theo, thực thi dòng đó ...

bạn có thể bắt gặp điều này khi bạn thực thi một tệp script và sau đó chỉnh sửa nó trước khi thực hiện xong. tập tin bat sẽ bị rối bởi điều này, nhưng tập tin cmd sẽ không.


Như đã được thiết lập, biến ComSpec env xác định chương trình nào được khởi chạy, về cơ bản bạn có nói rằng lệnh.com đọc tệp một dòng tại một thời điểm, trong khi cmd.exe tải trước tệp vào bộ nhớ? Bạn có thể trích dẫn một tài liệu tham khảo về điều này?
Chris Noe

24
Điều đó không đúng với Vista và XP, cả hai loại tệp đều được đọc theo từng dòng. Nếu bạn tạm dừng các tập tin .cmd hoặc .bat và chỉnh sửa nó, mã mới sẽ được thực hiện
Jeb


1
Người ta có thể tranh luận liệu đó có phải là từng dòng hay không, bởi vì nếu bạn tạm dừng thực thi ở giữa tệp lệnh và thêm một ký tự ở đầu, khi tiếp tục trình phân tích cú pháp sẽ bị tắt bởi một ký tự, có thể loại bỏ phần còn lại của tập lệnh.

2
Bạn không nên tranh luận .bat và .cmd không khác nhau theo cách đó. Cả hai luôn được đọc từng dòng. Bạn có thể kiểm tra nó nếu bạn không tin. Tạo một tệp bó mà echo 1&pausesau đó thực hiện nó. Bạn sẽ thấy 1Press any key to continue.... Trong khi tạm dừng thêm một dòng mới echo 2&pausevới trình soạn thảo bên ngoài. Nhấn một phím. Bạn sẽ thấy 2Press any key to continue.... Bạn thậm chí có thể thử thêm echo 3&pausevào đầu. Khi bạn nhấn một phím sau đó một lần nữa, bạn sẽ thấy 2.
venimus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.