2012-03-27 10 views
6

mia attuale linea di codice del lotto è:Scoppio di PER in lotti

for /L %%a in (8000,1,8100) do netstat /a /n | find "%%a" | find "LISTENING" || set tmp_freeport=%%a && goto found 

L'idea è quella di trovare un porto franco che verrà utilizzato per l'ascolto, all'interno della gamma di 8000-8100.

Attualmente, ho porta 8000 in uso, quindi lo script per andare dal 8001.

Dopo il ciclo, %tmp_freeport% è pari a 8001, come dovrebbe essere, e il suo valore viene utilizzato in seguito in modo corretto.

Il problema è che il loop continua a funzionare indipendentemente. netstat viene chiamato per cercare tutte le 101 porte dell'intervallo, che è ovviamente inefficace e indesiderato, perché la ricerca deve essere completata prima che lo script possa continuare.

Qualcuno può dirmi come uscire da un ciclo di ciclo FOR?

(In alternativa, se c'è un modo migliore di trovare un porto franco, si prega di vedere il mio somewhat-related question)

+1

hai provato la mia risposta? ha funzionato? –

risposta

5

Lei ha ragione che un FOR/L loop "sempre" conta fino a completamento. (Beh, in realtà ci sono alcuni metodi di codifica drastici che possono romperlo, ma non c'è bisogno di andare lì)

Tuttavia, anche se il ciclo conta fino al completamento, la clausola DO viene saltata una volta eseguita l'istruzione GOTO FOUND. Puoi provare a te stesso inserendo echo testing %%a& nella parte anteriore della tua clausola DO esistente. Vedrai che nessun test aggiuntivo avrà luogo una volta trovata la tua porta libera.

Il ciclo FOR/L conta molto velocemente (almeno per standard batch), quindi non mi preoccuperei del conteggio extra. Ora se il tuo contava da 1 a 1 milione, allora io potrei preoccuparmi di. A 10 milioni sono decisamente preoccupato.

Posso semplificare un po 'la logica esistente. È possibile combinare le 2 dichiarazioni FIND in un singolo FINDSTR utilizzando un'espressione regolare.

for /L %%a in (8000,1,8100) do netstat /a /n | findstr /rc:"%%a.*LISTENING" || set tmp_freeport=%%a && goto found 

Non sono un esperto in materia indirizzi IP e porte, ma io sono preoccupato del fatto che la logica TROVA può essere inadeguata per lo screening per le porte utilizzate. Penso che cercare un colon prima e uno spazio dopo il porto lo renderà più affidabile. Inoltre, dubito che tu voglia vedere il testo delle porte usate, quindi ho reindirizzato l'output di FINDSTR a nul.

for /L %%a in (8000,1,8100) do netstat /a /n | findstr /rc:":%%a .*LISTENING" >nul || set tmp_freeport=%%a && goto found 

Nota: GOTO: Label risolvere immediatamente tutte le altre forme di un ciclo for. Solo la variante FOR/L continua a contare dopo un GOTO.

+0

Ok, quindi anche se i comandi sono elencati quando ECHO è attivo, non vengono effettivamente eseguiti? È bello sapere, e spiega perché il risultato è ancora '8001'. –

4

È possibile utilizzare solo IF e GOTO. Qualcosa come:

SET /A a=8000 

:loop 

(Search and set variable here, use %a% instead of %%a, then GOTO found if found.) 

SET /A a=a+1 

IF %a% LEQ 8100 GOTO loop 

:found 
Problemi correlati