2016-07-21 15 views
5

Tôi đang cố gắng ghi nhật ký đầu ra của net stop trong khi cũng chụp ERRORLEVEL.ERRORLEVEL trong FOR/F Command Loop Trả về kết quả bất ngờ

Dựa trên this question, tôi đã cố gắng sau từ bên trong một chương trình con lồng nhau:

set /a loopIndex=0 
for /F "usebackq delims=" %%i in (`net stop %SERVICE_NAME%`) do (
if !loopIndex! EQU 0 if !errorlevel! EQU 1 set statementError=1 
set /a loopIndex+=1 
call :logMessage "%%i" 
) 
echo statementError: %statementError% 

Tuy nhiên, điều này không làm việc, ném 1 ngay cả khi net stop thành công.

Điều này có thể xảy ra nếu không có tệp tạm thời không? Nếu không, giải pháp tệp tạm thời sẽ như thế nào?

+0

ERRORLEVEL không phải là biến môi trường. Nó không cần phải được bao quanh với% hoặc! 'IF ErrorLevel 1' hoạt động tốt. –

+0

Đọc lại bài đăng được liên kết. * Ngoài trạng thái bên trong này, ** bạn có thể, nếu bạn muốn, tạo một biến môi trường có tên ERRORLEVEL **, giống như cách bạn có thể tạo một biến môi trường có tên FRED. Nhưng, như với FRED, biến đó sẽ không có bất kỳ ảnh hưởng nào đến mức lỗi. * (** Vùng nhấn mạnh **). –

+1

@KenWhite 'ERRORLEVEL' * là * biến môi trường tự động, giống như' CD', 'DATE' hoặc' RANDOM'. – dxiv

Trả lời

2

Trong khi @ của dbenham answer phù hợp cho trường hợp %ERRORLEVEL% trả về một giá trị nhị phân, tôi đã không thể xác nhận cũng không phủ nhận nếu các mã thoát được trả về cho net stop là trên thực tế nhị phân và do đó đã lựa chọn một giải pháp n-ary.

Theo @ dbenham của DOS tips forum post:

FOR /F "delims=" %%i IN ('net stop MyService 2^>^&1 ^& CALL ECHO %%^^ERRORLEVEL%%^>error.level') DO (
CALL :logMessage "%%i" 
) 
FOR /F "delims=" %%i IN (error.level) DO (SET /A statementError=%%i) 
DEL error.level 
IF %statementError% NEQ 0() 

Breaking xuống phân tích tuyên bố:

net stop MyService 2^>^&1 ^& CALL ECHO %%^^ERRORLEVEL%%^>error.level 
net stop MyService 2>&1 & CALL ECHO %^ERRORLEVEL%>error.level 
echo %ERRORLEVEL%>error.level 

Ở đây, CALL được sử dụng đặc biệt để trì hoãn phân tích cú pháp của %ERRORLEVEL% cho đến khi thực hiện ECHO.

+0

Vì tệp 'error.level' chứa một dòng duy nhất, bạn có thể đọc nó như' set/P statementError = "" <"error.level" ', hoặc, trong trường hợp tệp có thể không tồn tại hoặc trống,' bộ "statementError = 0" & set/P statementError = "" <"error.level" 2> nul' ... – aschipfl

2

Lệnh FOR/F thực thi STOP NET trong quy trình cmd.exe mới. FOR/F quy trình stdout, nhưng đó là nó. Không có cách nào cho tập lệnh chính xem bất kỳ giá trị biến nào mà lệnh FOR/F có thể tạo ra, vì chúng đã biến mất khi quá trình con chấm dứt.

Các giải pháp đơn giản và hiệu quả nhất sử dụng tệp tạm thời. Tôi giả sử NET STOP có hai mã lỗi có thể - Thành công = 0 và Lỗi = 1. Vì vậy, giải pháp đơn giản nhất là tạo một tệp tín hiệu lỗi tạm thời nếu có lỗi.

Sau đây chứng tỏ các khái niệm trong một cách chung chung:

@echo off 
del error.flag 2>nul 
for /f "delims=" %%A in ('net stop %SERVICE_NAME% ^|^| echo error>error.flag') do (
    ... 
) 
if exist error.flag (
    echo There was an error 
    del error.flag 
) 

Bạn có thể chỉ là một cách dễ dàng đưa các bài kiểm tra lỗi trong vòng DO() code nếu muốn.

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