2012-03-27 34 views
6

我目前的批次代碼行是:批量打破了出來

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

的想法是找到將用於監聽自由港的8000-8100的範圍內。

目前,我已經在使用8000端口,所以腳本應到8001

循環後,%tmp_freeport%等於8001,因爲它應該是,它的值後正確使用。

問題是,循環不管運行如何。調用netstat來搜索該範圍內的所有101個端口,這顯然是無效且不需要的,因爲搜索必須在腳本可以繼續之前完成。

誰能告訴我如何擺脫一批FOR循環?

(或者,如果有發現自由港的更好的方法,請參閱我的somewhat-related question

+1

你試過我的答案嗎?它工作? – 2012-03-27 16:34:19

回答

5

你是正確的,一個FOR/L循環「永遠」計數完成。 (嗯,實際上有一些嚴格的編碼方法可以打破它,但不需要去那裏)

但是,即使循環計數完成,一旦GOTO FOUND語句執行完畢,DO子句就會被跳過。您可以在現有的DO子句的前面插入echo testing %%a&來證明這一點。您會發現一旦找到自由端口,就不會再有其他測試發生。

FOR/L循環計數非常快(至少按批處理標準),所以我不擔心多餘的計數。現在如果你算1到1萬,那我可能擔心。在1000萬我絕對擔心。

我可以簡化你現有的邏輯。您可以使用正則表達式將2個FIND語句組合到一個FINDSTR中。

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

我不是IP地址和端口的專家,但我擔心你的FIND邏輯可能不足以篩選使用的端口。我認爲之前尋找一個冒號和港口後的一個空間將使它更可靠。另外,我懷疑你想看到使用的端口的文本,所以我將FINDSTR輸出重定向到nul。

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

注: GOTO:標籤將立即終止所有其他形式的for循環。 GOTO後只有FOR/L變量繼續計數。

+0

好的,即使ECHO打開時列出了命令,它們實際上並未被執行?這很好理解,並解釋了爲什麼結果仍然是'8001'。 – 2012-03-27 20:02:51

4

你可以用IF和GOTO來代替。例如:

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