簡體   English   中英

循環的批處理腳本不起作用

[英]Batch script for loop not working

我需要有多個遠程管理員在站點測試他們的下載速度。 Speedtest.net等都不是我們廣域網性能的真正指標。 我不希望使用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並將塊封閉,所以它停止工作。 任何人都可以解釋為什么會失敗嗎?

謝謝!

在FOR循環中使用GOTO總是會打破循環 - 使用GOTO后不會發生剩余的迭代。

這是因為CMD.EXE的工作方式。 括號內的整個命令塊被解析並一次性加載到內存中。 每次迭代都會執行存儲在內存中的已解析命令。 這些解析的命令不包含任何標簽。 GOTO必須掃描文件,這需要打破循環。

STARTTIME的“消失”值也與整個塊被立即解析的事實有關。 %STARTTIME%在分析時擴展,但在執行任何塊之前解析該命令。 因此,您將獲得執行FOR命令之前存在的值,這可能是未定義的。 有一個稱為延遲擴展的功能,可用於在執行時獲取變量的值而不是解析時間。 從命令提示符下鍵入HELP SET ,並閱讀有關延遲擴展的部分,該部分從文檔的一半開始。

但是有一種簡單的方法可以使代碼工作 - 只需將DO塊的內容移動到子程序,然后在循環中調用例程。 (我假設您在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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM