Perché errorlevel 0 anche se la stringa non viene trovata?


1

Se eseguo questo codice:

:loop
(type "File" | findstr Idle) > nul 2>&1
timeout 1
if errorlevel 1 goto loop

Quindi se la stringa "Idle" non può essere trovata all'interno di File, ricomincerà da "loop" e continuerà a farlo fino a quando non verrà trovato "Idle" a quel punto si sposterà ulteriormente nel codice. Va tutto bene, e se il mio codice fosse strutturato in modo che fosse in fondo al codice piuttosto che in alto, le cose andrebbero bene qui, ma ho bisogno che questo sia il primo comando (quindi se viene trovato Idle , ripeti questo ciclo, se non viene trovato il minimo, scorri verso il basso)

Ma quando eseguo questo codice:

:loop
(type "File" | findstr Idle) > nul 2>&1
timeout 1
if errorlevel 0 goto loop

Ricomincerà sempre da "loop" indipendentemente dal fatto che sia possibile trovare la stringa "Idle".

Ho davvero bisogno di essere in grado di eseguire un comando se viene trovata la stringa (piuttosto che se la stringa non viene trovata (non sto pianificando di usare "goto" qui, ho bisogno di eseguire comandi specifici (come "goto") quando " Inattivo "viene trovato e un altro set di comandi quando non viene trovato, quindi ho bisogno di due livelli di errore validi o di un'alternativa).

Perché questo non funziona e quale altro modo c'è di fare questo?

Risposte:


2

Dovresti leggere un po 'di documentazione. Puoi iniziare digitando help ifo if /?dalla riga di comando e, se leggi attentamente, vedrai un problema con la tua logica.

IF ERRORLEVEL 0significa "restituisce VERO se ERRORLEVEL è> = 0". Questo sarà sempre vero dopo aver eseguito FINDSTR.

Se non hai avuto il TIMEOUT prima del tuo IF, puoi semplicemente usare la condizione IF NOT ERRORLEVEL.

:loop
(type "File" | findstr Idle) > nul 2>&1
if not errorlevel 1 goto loop

Ma la logica viene distrutta quando si aggiunge il comando TIMEOUT perché cancella ERRORLEVEL su 0. Quindi è necessario salvare il valore nella propria variabile prima di eseguire TIMEOUT.

:loop
(type "File" | findstr Idle) > nul 2>&1
set err=%errorlevel%
timeout 1
if %err% == 0 goto loop

Ma vorrei usare &&invece:

:loop
type "File" | findstr Idle >nul 2>nul && (timeout 1 & goto :loop)

O meglio ancora:

:loop
findstr Idle "File" 2>nul >nul && (timeout 1 & goto :loop)

in caso contrario, il livello di errore 1 mi dà lo stesso risultato del livello di errore 0 (ad esempio, passa sempre) che in realtà avevo già provato. La tua soluzione alternativa funziona piuttosto bene anche se +1.
Cestarian,

@Cestarian - No, SE ERRORORLEVEL 0 è vero se ERRORLEVEL> = 0, mentre SE NON ERRORLEVEL 1 è vero se ERRORLEVEL <1.
dbenham,

Sì, e grazie alla tua nota sull'aiuto se sono stato in grado di scoprire che il livello di errore può essere trattato come qualsiasi altra variabile, e ho anche visto che effettivamente il livello di errore funziona come dici tu (se il livello di errore 0 è vero se il livello di errore> = 0). Ma questo non cambia il fatto che "if not errorlevel 1 goto loop" non funziona. Sto usando echo per dirmi qual è il livello di errore, e per me non passerà attraverso questa affermazione anche se il livello di errore è 1. Se trovi un modo che funziona davvero (utilizzando il livello di errore), accetterò questa risposta.
Cestarian

dannazione, mostra un comportamento davvero strano, ho provato un sacco di cose. Ad esempio, se% errorlevel% neq 1 goto loop passerà anche se errorlevel è 1 (come nel goto loop). Tuttavia, se faccio neq 0 , continuerà ogni volta sotto il ciclo (anche se il livello di errore è 1). Non ti sta facendo questo?
Cestarian,

@Cestarian - era il comando TIMEOUT che cancellava ERRORLEVEL. Ho aggiornato la mia risposta. Inoltre, si potrebbe considerare di rimuovere il tuo downvote da stackoverflow.com/a/13476936/1012053 (sto supponendo che era)
dbenham

0

Alla fine ho trovato una soluzione alternativa. (Funziona solo perché la stringa è la prima riga nel mio file)

:loop
set /p var=<File
timeout 1
if "%var%"=="Idle" goto loop

Questo ha funzionato per me, ma vorrei comunque una risposta al motivo per cui i livelli di errore non funzionano come pubblicizzato, o se li sto semplicemente fraintendendo (la risposta corretta andrà a chiunque spieghi perché il codice nella domanda originale non funziona)


Funziona solo se "Idle" è la prima riga del tuo file, il che non è implicito nella tua domanda.
dbenham,

@dbenham Sì, questo non è mai stato un problema, e come ho detto nella mia risposta, questa non è esattamente una risposta perfetta alla mia domanda.
Cestarian
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.