批量打破FOR

时间:2012-03-27 15:53:04

标签: batch-file for-loop cmd netstat

我目前的批次代码是:

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

2 个答案:

答案 0 :(得分:5)

你是对的,FOR / L循环“总是”计为完成。 (嗯,实际上有一些激烈的编码方法可以打破它,但不需要去那里)

但是,即使循环计数完成,也会在执行GOTO FOUND语句后跳过DO子句。您可以通过在现有DO子句的前面插入echo testing %%a&来证明这一点。一旦找到空闲端口,您将看到没有其他测试。

FOR / L循环计数非常快(至少按批次标准),所以我不担心额外的计数。现在,如果你的数量是1到100万,那么我可能担心。 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:Label会立即终止所有其他形式的FOR循环。在GOTO之后,只有FOR / L变体继续计数。

答案 1 :(得分: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