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ループは(少なくともバッチ標準では)非常に高速にカウントされるため、余分なカウントについて心配する必要はありません。今、あなたが100万から100万を数えているなら、私は心配するかもしれません。1000万で私は間違いなく心配しています。

既存のロジックを少し単純化できます。正規表現を使用して、2つのFINDステートメントを1つの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 に答える