1

複数のリモート管理者にサイトでダウンロード速度をテストしてもらう必要があります。Speedtest.net などは、WAN のパフォーマンスの真の指標ではありません。リモート管理者の技術的な知識と労力を最小限に抑える必要があるため、iperf を使用したくありません。何もインストールする必要もありません。したがって、テスト ファイルを 5 回ダウンロードするには、単純なバッチ ファイルが必要です。これは私がこれまでに持っているものです:

@echo off
rem localize variables to this script
setlocal
rem delete the test file if it already exists
if exist %HomePath%\Downloads\100meg.test del %HomePath%\Downloads\100meg.test
rem perform the test 5 times
for /l %%i IN (1,1,5) DO (
    rem mark the start time
    set STARTTIME=%TIME%
    echo Download started at:%STARTTIME%
    rem start download
    C:\windows\explorer.exe http://mirror.internode.on.net/pub/test/100meg.test
    rem check for file download completion
    :while
        if exist %HomePath%\Downloads\100meg.test goto wend
        goto while
    :wend
    rem mark the end time
    set ENDTIME=%TIME%
    echo Download completed at:%ENDTIME%
    rem convert STARTTIME and ENDTIME to centiseconds
    set /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100)
    set /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100)
    rem calculate the time taken in seconds
    set /A DURATION=(%ENDTIME%-%STARTTIME%)/100
    echo Download took:%DURATION% seconds
    rem delete the test file ready for next iteration
    del %HomePath%\Downloads\100meg.test
)

問題は、 for を追加してブロックを括弧で囲んだため、機能しなくなったことです。なぜこれが失敗しているのか、誰かが光を当てることができますか?

ありがとう!

4

1 に答える 1

3

FOR ループ内で GOTO を使用すると、常にループが中断されます。GOTO を使用すると、残りの反復は発生しません。

これは、CMD.EXE の動作が原因です。括弧内のコマンドのブロック全体が解析され、一度にメモリにロードされます。各反復では、メモリに保存されている既に解析されたコマンドが実行されます。これらの解析済みコマンドには、ラベルは含まれません。GOTO はファイルをスキャンする必要があるため、ループを中断する必要があります。

STARTTIME の「消える」値は、ブロック全体が一度に解析されるという事実にも関係しています。%STARTTIME%解析時に展開されますが、コマンドはブロックが実行される前に解析されます。したがって、FOR コマンドが実行される前に存在していた値を取得していますが、これはおそらく未定義です。解析時間ではなく実行時に変数の値を取得するために使用できる、遅延展開と呼ばれる機能があります。コマンドプロンプトHELP SETから入力し、ドキュメントの途中から始まる遅延展開に関するセクションを読みます。

しかし、コードを機能させる簡単な方法があります。DO ブロックの内容をサブルーチンに移動し、ループ内でそのルーチンを CALL するだけです。(DO句内のロジックが正しいと仮定しています)。CALL はループを壊しません:-)

メイン コードがサブルーチンを通過しないように、ルーチン ラベルの前に EXIT /B を忘れずに付ける必要があります。

@echo off
rem localize variables to this script
setlocal
rem delete the test file if it already exists
if exist %HomePath%\Downloads\100meg.test del %HomePath%\Downloads\100meg.test
rem perform the test 5 times
for /l %%i IN (1,1,5) do call :downloadTest
exit /b

:downloadTest
rem mark the start time
set STARTTIME=%TIME%
echo Download started at:%STARTTIME%
rem start download
C:\windows\explorer.exe http://mirror.internode.on.net/pub/test/100meg.test
rem check for file download completion
:while
  if exist %HomePath%\Downloads\100meg.test goto wend
  goto while
:wend
rem mark the end time
set ENDTIME=%TIME%
echo Download completed at:%ENDTIME%
rem convert STARTTIME and ENDTIME to centiseconds
set /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100)
set /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100)
rem calculate the time taken in seconds
set /A DURATION=(%ENDTIME%-%STARTTIME%)/100
echo Download took:%DURATION% seconds
rem delete the test file ready for next iteration
del %HomePath%\Downloads\100meg.test
exit /b
于 2012-11-14T01:34:07.513 に答える