2012-06-07 19 views
17

Giới thiệu

Có rất nhiều lời khuyên trên mạng để đối phó với mã trở lại trong các tập tin batch (sử dụng cơ chế ERROLEVEL), ví dụcách hết sức rõ ràng để kiểm tra khác không (lỗi) mã trở lại trong cửa sổ hàng loạt tập tin

Một số lời khuyên là để làm if errorlevel 1 goto somethingbad, trong khi những người khác khuyên bạn sử dụng các %ERRORLEVEL% biến và sử dụng ==, EQU, LSS vv Dường như có vấn đề trong vòng IF tuyên bố và như vậy, do đó, sau đó chậm trễ mở rộng được khuyến khích, nhưng nó dường như đi kèm với quirks của riêng mình.

Câu hỏi

gì là hết sức rõ ràng (ví dụ mạnh mẽ, vì vậy nó sẽ làm việc trên gần như bất kỳ hệ thống với gần bất kỳ mã trở về) cách nào để biết nếu một xấu (khác không) mã đã được trả lại?

nỗ lực của tôi

Đối với sử dụng cơ bản, sau đây dường như làm việc ok để bắt bất kỳ mã trả lại khác không:

if not errorlevel 0 (
    echo error level was nonzero 
) 

Trả lời

34

Xin lỗi, nỗ lực của bạn không phải là thậm chí gần gũi. if not errorlevel 0 chỉ đúng nếu errorlevel là số âm.

Nếu bạn biết errorlevel rằng sẽ không bao giờ tiêu cực, sau đó

if errorlevel 1 (echo error level is greater than 0) 

Nếu bạn phải cho phép errorlevel tiêu cực, và không phải là trong một khối trong ngoặc mã, sau đó

Note - Tôi đã chỉnh sửa câu trả lời của mình để xóa rõ ràng mọi giá trị errorlevel do người dùng xác định sau khi đọc nhận xét của Joey về câu trả lời được liên kết trong câu hỏi. Một errorlevel do người dùng định nghĩa có thể che dấu giá trị động mà chúng tôi đang cố truy cập. Nhưng điều này chỉ hoạt động nếu tập lệnh của bạn có tiện ích mở rộng .bat. Các tập lệnh có phần mở rộng là .cmd sẽ đặt ERRORLEVEL của bạn thành 0 nếu bạn đặt hoặc xóa biến! Để làm cho vấn đề tồi tệ hơn, XP sẽ đặt ERRORLEVEL thành 1 nếu bạn cố gắng xác định một biến không tồn tại. Đó là lý do tại sao tôi xác định rõ ràng một biến ERRORLEVEL trước khi tôi cố xóa nó!

Nếu bạn nằm trong một khối trong ngoặc mã sau đó bạn phải sử dụng mở rộng chậm để có được giá trị hiện tại

setlocal enableDelayedExpansion 
(
    SomeCommandThatMightGenerateAnError 
    set "errorlevel=1" 
    set "errorlevel=" 
    if !errorlevel! neq 0 (echo error level is non-zero) 
) 

Nhưng đôi khi bạn không muốn trì hoãn việc mở rộng kích hoạt. Tất cả sẽ không bị mất nếu bạn muốn kiểm tra mức độ lỗi ngay lập tức sau khi thực hiện một lệnh.

(
    SomeCommandThatMightGenerateAnError && (echo Success, no error) || (echo There was an error) 
) 

Nếu bạn hoàn toàn phải kiểm tra giá trị ERRORLEVEL động mà không sử dụng mở rộng trễ trong khối được chặn, thì các công trình sau đây. Nhưng nó có mã xử lý lỗi ở hai nơi.

(
    SomeCommandThatMightGenerateAnError 
    if errorlevel 1 (echo errorlevel is non-zero) else if not errorlevel 0 (echo errorlevel is non-zero) 
) 


Ở đây, sau cùng, là "cuối cùng" thử nghiệm cho khác không errrolevel nên hoạt động dưới bất kỳ hoàn cảnh :-)

(
    SomeCommandThatMightGenerateAnError 
    set foundErr=1 
    if errorlevel 0 if not errorlevel 1 set "foundErr=" 
    if defined foundErr echo errorlevel is non-zero 
) 

Nó thậm chí có thể được chuyển đổi thành macro để dễ sử dụng:

set "ifErr=set foundErr=1&(if errorlevel 0 if not errorlevel 1 set foundErr=)&if defined foundErr" 
(
    SomeCommandThatMightGenerateAnError 
    %ifErr% echo errorlevel is non-zero 
) 

Macro hỗ trợ dấu ngoặc đơn và ELSE tốt:

%ifErr% (
    echo errorlevel is non-zero 
) else (
    echo errorlevel is zero 
) 


Một vấn đề cuối cùng:

Redirection của đầu vào và/hoặc đầu ra có thể thất bại đối với bất kỳ số lý do. Nhưng lỗi chuyển hướng thực hiện không đặt errorlevel trừ khi toán tử || được sử dụng. Xem File redirection in Windows and %errorlevel% để biết thêm thông tin. Vì vậy, người ta có thể lập luận rằng không tồn tại một cách chống lừa đảo để kiểm tra lỗi thông qua errorlevel. Phương pháp đáng tin cậy nhất (nhưng vẫn không thể sai) là toán tử ||.

+2

Cần lưu ý rằng errorlevel là [không phải là biến môi trường] (http://blogs.msdn.com/b/oldnewthing/archive/2008/09/26/8965755.aspx). –

+0

@NickWestgate - Yep, ERRORLEVEL là một trong nhiều biến "giả" hoặc "động". Tôi đã xác định và ghi lại ba loại biến "động" tại http://stackoverflow.com/a/20169219/1012053 và trong bài đăng đó tôi tham khảo cùng một blog của Raymond Chen. – dbenham

+0

EDIT 2016-06-03: Tôi đã sửa đổi mã để xóa bất kỳ ERRORLEVEL do người dùng xác định nào đối với hành vi XP đặt ERRORLEVEL thành 1 nếu bạn cố gắng xác định biến không tồn tại. – dbenham

Các vấn đề liên quan