8

我当前的批处理代码行是:

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 循环?

(或者,如果有更好的方法来寻找自由港,请参阅我的相关问题

4

2 回答 2

6

你是正确的,一个 FOR /L 循环“总是”算作完成。(嗯,其实有一些极端的编码方法可以破解它,但没必要去那里)

然而,即使循环计数完成,一旦执行了 GOTO FOUND 语句,DO 子句也会被跳过。您可以通过echo testing %%a&在现有 DO 子句的前面插入来证明这一点。一旦你找到你的自由端口,你会看到没有额外的测试发生。

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 循环。只有 FOR /L 变体在 GOTO 之后继续计数。

于 2012-03-27T19:09:59.487 回答
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
于 2012-03-28T00:41:47.323 回答