Như một số câu trả lời / nhận xét khác lưu ý, ý tưởng rằng phải có khoảng trắng sau lệnh không đúng. Một ví dụ nổi tiếng là bạn có thể gõ một dấu gạch chéo về phía trước sau một lệnh, mà không cần một khoảng trắng trước.
Tuy nhiên, có một hành vi khác ít được hiểu hơn và cho phép " cd..
" mà bạn đang hỏi về. Hành vi này cũng cho phép " cd\
" hoạt động.
Hành vi mà bạn mô tả là phù hợp cho tất cả các lệnh bên trong trình thông dịch dòng lệnh. Nếu bạn có một số ký hiệu nhất định, bao gồm dấu chấm, dấu gạch chéo hoặc dấu gạch chéo ngược, thì các ký tự trước được kiểm tra để xem liệu chúng có phải là lệnh bên trong trình bao "trình thông dịch dòng lệnh" hay không (CMD.EXE hoặc tiền thân của nó ).
Điều này có thể được thực hiện trước khi kiểm tra xem từ có thể đề cập đến một tập tin hoặc thư mục con. Điều đó đúng với cd
lệnh. Đáng thương thay, khi tạo một mẫu, tôi thấy rằng điều này không xảy ra với copy
lệnh, vì vậy kết quả không nhất quán: chúng không nhất thiết giống nhau với tất cả các lệnh nội bộ. Tôi đã không tiếp tục tìm kiếm để so sánh (nhiều) dòng lệnh khác del
và dir
vì vậy tôi chỉ đề nghị cực kỳ cẩn thận nếu bạn cố gắng dựa vào những gì xảy ra mà không có khoảng trắng.
Bây giờ, câu hỏi cũng được hỏi về lệnh echo : Đây là một ngoại lệ bất thường, theo tôi nghĩ echo.
là khá nổi tiếng bởi các chuyên gia DOS. Điều này có lẽ đã được ghi nhận. Hành vi, ít nhất là trong CMD của Win7 , là nếu lệnh bắt đầu bằng " echo.
", thì khoảng thời gian đầu tiên bị bỏ qua. Vì vậy, " echo..hi
" biến thành đầu ra của " .hi
". Lý do cho điều này là để " echo.
" có thể được sử dụng để in một dòng trống. Ngược lại, với Unix, bạn có thể thực hiện việc này một cách đơn giản bằng cách tự chạy echo
lệnh "". Tuy nhiên, trong DOS, tự chạy echo
lệnh "" sẽ tạo ra cài đặt " echo " hiện tại . Tương tự, DOS xử lý " Echo *Off*
" và "Echo *On*
"là các giá trị đặc biệt thay đổi cài đặt tiếng vang hiện tại. Nếu bạn thực sự muốn in từ" Off
", thì" Echo.Off
"thực hiện thủ thuật (ít nhất là với các phiên bản đủ của trình thông dịch dòng lệnh CMD gần đây của Microsoft .)
Vì vậy, ít nhất echo
lệnh có một lời giải thích bán hợp lý. Đối với các lệnh còn lại, tôi thường nghĩ rằng các lệnh nội bộ được ưu tiên. Tuy nhiên, khi tôi cố gắng thực hiện một số thử nghiệm, tôi thấy điều đó thực sự không nhất quán. Tôi chứng minh điều này thông qua một số ví dụ mà tôi đã ghi lại ở đây.
Dưới đây là một số ví dụ. Tôi đã sử dụng một dấu nhắc lệnh nâng cao, để UAC không hiểu tôi viết vào thư mục gốc. Điều này đã được thực hiện với CMD.EXE của Microsoft Windows 7. Tôi nghi ngờ các hành vi có thể khác với các phiên bản khác, chẳng hạn như.COM.COM từ các phiên bản MS-DOS cũ hơn hoặc phần mềm được phát hành bởi các công ty khác (DR-DOS's INTERN.COM).
(Câu trả lời này đã khá dài rồi, vì vậy tôi không bao gồm các lệnh để dọn sạch tất cả mớ hỗn độn tôi đã tạo trên hệ thống tập tin của mình. Có một chút dọn dẹp, nhưng không nhiều.)
Dưới đây là một ví dụ chứng minh rằng lệnh nội bộ tạo ra quyền ưu tiên. (Tôi cũng chứng minh khả năng ít được biết đến là sử dụng dấu hai chấm để nhận xét một cách hiệu quả, cũng hoạt động tốt trong các tệp bó. Về mặt kỹ thuật, trong các tệp bó, nó được xử lý như một nhãn không thể đạt được bởi GOTO và kết thúc trở nên nhanh hơn lệnh REM.)
C: \ Something > md cd
C: \ Something > echo echo subir >> cd \ a.bat
C: \ Something > md \ a
C: \ Something > . \ Cd \ a.bat
subir
C: \ Something > :: Nó chạy từ thư mục con
C: \ Something > cd \ a
C: \ a> :: Điều đó đã thay đổi thư mục hiện tại của tôi, vì vậy cd được ưu tiên
Cập nhật: Sau khi thử nghiệm thêm, tôi thấy rằng lệnh cd nội bộ chỉ được ưu tiên hơn hệ thống tập tin nếu thư mục được chỉ định không bao gồm một khoảng thời gian. Vì vậy, nếu bạn có một thư mục có tên " a.bat ", thì bạn có thể chạy " **cd\a.bat**
" và tệp bó sẽ chạy.
Việc khám phá hành vi ít phổ biến này (vì hầu hết các thư mục có thể không có thời gian trong đó) khiến tôi phải cập nhật những phát hiện của mình. Hóa ra lệnh cd thực sự hoạt động giống với lệnh sao chép hơn tôi nghĩ ban đầu.
Mặc dù ban đầu tôi nghĩ rằng các lệnh cd và copy đang hoạt động khác nhau, nhưng bây giờ tôi đã hiểu ra rằng đó là do mô hình của các tên tôi đang cung cấp. Tuy nhiên, tôi đã xem xét các kết quả trước đó của mình và xác định rằng các thử nghiệm được ghi lại trước đó của tôi giúp thể hiện một số khác biệt giữa những gì xảy ra khi một tên bao gồm một khoảng thời gian và một phần mở rộng và khi nó không. Vì vậy, tôi vẫn bao gồm những phát hiện cũ hơn của tôi bên dưới (hầu như không thay đổi, nhưng với một số cập nhật rất nhỏ nên những gì tôi nói là chính xác).
Dưới đây là một ví dụ minh họa bản sao , với một đường dẫn đầy đủ, không sử dụng cùng mức ưu tiên (ưu tiên lệnh nội bộ) như cd khi không sử dụng tiện ích mở rộng:
C: \ Something > echo echo root >> \ try.bat
C: \ Something > md copy
C: \ Something > echo echo thư mục con >> copy \ try.bat
C: \ Something > . \ Copy \ try.bat chạy từ thư mục con thư mục
con
C: \ Something > copy \ try.bat
thư mục con
C: \ Something > :: Huh? Tại sao không ghi đè và chạy từ gốc?
C: \ Something> :: Rõ ràng, lệnh sao chép nội bộ không được ưu tiên kiểm tra thư mục con và tên tệp đầy đủ (mặc dù lệnh cd nội bộ đã được ưu tiên, khi thư mục không có phần mở rộng)
C: \ Something> ::
C: \ gì đó>:: Một thử nghiệm khác: Tôi có thể thêm các khoảng thời gian vô dụng vào cuối
C: \ Something > . \ Copy .. \ try.bat
thư mục con
C: \ Something > :: Được rồi, tuyệt vời. Nhưng sau đó, điều này sẽ không kiểm tra thư mục con:
C: \ Something > copy .. \ try.bat
1 tệp đã được sao chép.
C: \ Something> :: Điều đó đã chạy lệnh sao chép nội bộ
Những phát hiện ban đầu của tôi chỉ ra rằng những kết quả này chứng minh rằng trình vỏ dòng lệnh ưu tiên:
- vào hệ thống tập tin (thay vì lệnh sao chép nội bộ ) khi chỉ định dấu gạch chéo ngược ngay sau tên của lệnh nội bộ
- vào lệnh cd nội bộ (thay vì hệ thống tập tin) khi chỉ định dấu gạch chéo ngược ngay sau tên của lệnh nội bộ.
- vào lệnh sao chép nội bộ (thay vì hệ thống tập tin) khi chỉ định một khoảng thời gian ngay sau tên của lệnh nội bộ.
Điều này chứng tỏ rõ ràng rằng hành vi không nhất quán giữa lệnh sao chép (với tên tệp đầy đủ bao gồm cả phần mở rộng) và lệnh cd (không có phần mở rộng như một phần của tên thư mục). Khi sử dụng dấu gạch chéo ngược, lệnh sao chép (có phần mở rộng tên tệp đầy đủ) sẽ kiểm tra hệ thống tệp trước, nhưng lệnh cd sẽ không (nếu thư mục không chứa phần mở rộng).
(Cập nhật: Ban đầu, tôi nghĩ rằng sự không nhất quán dựa trên hành vi khác nhau giữa các chương trình. Sau đó, tôi phát hiện ra rằng sự không nhất quán đã tồn tại, nhưng được gây ra nhiều hơn từ các tham số được cung cấp.)
Trên thực tế, ngay cả những gạch đầu dòng đó cũng không hoàn toàn chính xác, mặc dù tôi dường như chỉ chứng minh mọi điều cá nhân tôi vừa nói. Vấn đề là, danh sách các gạch đầu dòng đó không đủ chính xác để hoàn toàn chính xác. (Tôi đã để lại những thứ không chính xác để những điểm đạn đó có thể được so sánh tương đối dễ dàng và được kiểm tra tương đối dễ dàng.)
Tuy nhiên, để chính xác hơn, dấu đầu dòng đầu tiên phải chỉ ra rằng vỏ dòng lệnh ưu tiên:
- đến hệ thống tập tin (thay vì lệnh sao chép nội bộ ) khi chỉ định dấu gạch chéo ngược và sau đó là phần còn lại của đường dẫn đầy đủ, ngay sau tên của lệnh nội bộ
Những điều sau đây sẽ chứng minh tại sao tôi lại tạo ra sự khác biệt đó:
C: \ ở nơi khác> echo Độ cao UAC cần thiết cho dòng này >> \ Needext
C: \ ở nơi khác> echo Độ cao UAC cần thiết cho dòng này >> \ Needext.bat
C: \ ở nơi khác> md. \ Copy
C: \ ở nơi khác> echo @ Echo subdir >> copy \ needext.bat
C: \ nơi khác> . \ copy \ needext
subdir
C: \ nơi khác> sao chép \ needext.bat
subdir
C: \ nơi khác> copy \ needext
1 file (s) sao chép.
C: \ nơi khác> :: UAC cũng cần thiết cho các dòng tiếp theo
C: \ nơi khác> del \ Needext
C: \ nơi khác> del \ Needext.bat
(Lưu ý rằng lệnh sao chép cuối cùng đã tìm tệp có tên \ Needext , vì lệnh sao chép nội bộ đã được sử dụng. Tệp \ Needext.bat chỉ được tạo để giúp dễ dàng hiển thị rằng nó không bao giờ được sử dụng bởi các dòng lệnh có chứa bản sao từ .)
Tại thời điểm này, tôi đã thiết lập một số điểm không nhất quán (với hành vi của lệnh sao chép ) khi sử dụng dấu gạch chéo ngược ...
Tiếp theo tôi sẽ chứng minh rằng có một số thống nhất giữa các lệnh này. (Vì vậy, có tính nhất quán ... ừm ... đôi khi. Chúng ta chỉ có thể có tính nhất quán, không nhất quán.) Điều tôi sẽ trình bày tiếp theo là lệnh cd hoạt động thay vì lệnh sao chép khi sử dụng một khoảng thời gian. Lệnh sao chép sử dụng lệnh nội bộ và lệnh cd cũng vậy .
C: \ Something > md. \ Yetmore
C: \ Something > cd. \ Yetmore
C: \ Something \ yetmore> md. \ Md
C: \ Something \ yetmore> echo echo subir >> md \ test.bat
C: \ Something \ yetmore> . \ md. \ test
subir
C: \ Something \ yetmore> md. \ test
C: \ Something \ yetmore> md. \ test
Một thư mục con hoặc tệp. \ test đã tồn tại.
C: \ Something \ yetmore> :: Lỗi đó cho thấy chúng tôi đã chạy lệnh nội bộ.
C: \ Something \ yetmore> md .. \ test
C: \ Something \ yetmore> md. \ Cd
C: \ Something \ yetmore> copy. \ Md cd
. \ Md \ test.bat
1 tệp đã được sao chép.
C: \ Something \ yetmore> . \ Cd. \ Test
subir
C: \ Something \ yetmore> cd. \ Test
C: \ Something \ yetmore \ test> :: lệnh nội bộ hoạt động với một khoảng thời gian
C: \ Something \ yetmore \ test> cd ..
C: \ Something \ yetmore> . \ cd .. \ test
subir
C: \ Something \ yetmore> cd .. \ test
C: \ Something \ test> :: lệnh nội bộ cũng được ưu tiên khi hai giai đoạn đã sử dụng
Vì vậy, trong phiên kiểm tra ban đầu chủ yếu tập trung vào các lệnh sao chép và cd (với một số sử dụng bổ sung của md và một chút del ), lần duy nhất chúng tôi thực sự có hệ thống tập tin ưu tiên là với lệnh sao chép , và sau đó là hệ thống tập tin chỉ được ưu tiên khi sử dụng đường dẫn đầy đủ.
Sau khi xem xét tiếp theo, tôi thấy rằng lệnh cd cũng ưu tiên hệ thống tập tin khi sử dụng tiện ích mở rộng. Ít nhất điều này có nghĩa là các lệnh nội bộ đang được xử lý phù hợp hơn với nhau một chút. Tuy nhiên, điều đó cũng có nghĩa là chúng ta có các hành vi khác nhau dựa trên tên của các đối tượng hệ thống tệp (các tệp hoặc thư mục). Điều đó có vẻ như hành vi đang sử dụng một số logic bên trong thực sự, thực sự tối nghĩa. Do đó, dựa vào hành vi này để hoạt động trên các hệ điều hành khác nhau là điều mà tôi có thể coi là không an toàn để làm.